Меню Закрыть

Stm32f4 hal user manual pdf


Делюсь небольшой проделанной работой — это частичный перевод оригинального описания

STM32Cube является оригинальной разработкой STMicroelectronics, предназначенной для разработчиков программного обеспечения (ПО), встроенного в микроконтроллеры STM32. STM32Cube облегчает разработку ПО за счет снижения усилий, времени и затрат, и охватывает всё семейство микроконтроллеров STM32.

STM32CubeTM версии 1.x включают в себя:

  • STM32CubeMX — утилита с графическим интерфейсом, предназначенная для генерации кода инициализации STM32 и встроенной в микроконтроллер периферии.
  • Комплексное программное обеспечение для встраиваемых платформ, сконфигурированное для конкретной серии (например, STM32CubeF4 для серии STM32F4):
  • STM32Cube HAL, встраеваемое программное обеспечение уровня абстракции HAL, для STM32, обеспечивающее максимальную переносимость кода внутри семейства STM32
  • Набор встраиваемых компонентов ПО, таких как RTOS, USB, FatFS, TCP/IP, Graphics, настроенный для их совместной работы
  • Полный комплект примеров, для всех программых компонентов и утилит, находящихся в наборе ПО.

Драйверы уровня HAL представляют собой комплект универсальных, многофункциональных, и одновременно простых интерфейсов API, предназначенных для взаимодействия МК с верхним слоем ПО (основной программой, библиотеками и стеками). Драйверы могут иметь как общий (generic), так и расширенный (extension) API.

HAL разработан для применения такой архитектуры программирования, когда необходимые функции выполняются верхним слоем приложения, за счет применения промежуточного уровня HAL. При такой архитектуре программирования верхний уровень приложения не «привязан» к микроконтроллеру (МК), т.к обращается к ресурсам МК только через библиотеку драйверов HAL. Такая структура пользовательского приложения улучшает повторное использование кода, и гарантирует его легкую переносимость на другие устройства STM32.

Драйверы HAL предоставляют полный набор готовых к использованию API, которые упрощают реализацию пользовательского приложения. В качестве примера — встроенные устройства коммуникации (связи) содержат интерфейсы API для инициализации и настройки устройства, управления передачей данных на основе опроса, в прерываниях или через DMA, а так же для управления ошибками связи.

API-интерфейсы драйверов HAL, делятся на две категории: 1) Общие (generic) API, которые обеспечивают общие, для всех серий STM32, функции. 2) Расширенные (extension) API, которые содержат специфические или индивидуальные функции для данного семейства или его части.

Драйверы HAL являются функционально-ориентированными, а не ориентированны на внутренние периферийные устройства. Например, API таймера делится на несколько категорий, по функциям, предоставляемым внутренним устройством таймера: базовый таймер (basic timer), захвата (capture), широтно-импульсной модуляции (PWM), и т.д…

Исходный код библиотеки драйверов разработан в соответствии со Strict ANSI-C, что делает код независимым от инструментов разработки. Весь исходный код проверен с помощью инструмента статистического анализа CodeSonarTM, полностью документирован и является MISRA-C 2004 совместимым.

Драйверы слоя HAL реализуют обнаружение ошибок во время выполнения (run-time failure detection), HAL проверяет входные значения всех функций. Такая динамическая проверка способствует повышению надежности встроенного ПО. Обнаружение ошибок во время выполнения программы, также, способствует ускорению разработки пользовательских приложений и процесса отладки.

Далее — в приложенном файле

Сразу скажу, что переведена, фактически, только 2 глава, в которой описано, как устроен HAL. Старался перевести максимально «корректно», а как получилось…
Если кем-то будут замечены ляпусы — исправлю.
Обсуждение на форуме

Читайте также:  Shadow of the tomb raider настройки графики

Урок 5

Сегодня мы попробуем поработать с таймерами также с помощью библиотеки HAL.

У нашего контроллера STM32F407 таймеров много.

Открываем reference manual и перейдём в главу 17 — Advanced-control timers (TIM1&TIM8).

Данные таймеры — это таймеры с расширенным управлением. Таких таймеров всего два

Далее открываем следующий пункт 19 — General-purpose timers (TIM9 to TIM14).

Это таймеры общего назначения. У них функционал очень ограничен, зато их у нас целых шесть

Далее идем в пункт 20.2 TIM6&TIM7 main features

Данные таймеры — базовые. Функционал немного расширен

Также надо отметить особо таймеры 2 и 5, которые являются 32-битными, что не может не заинтересовать разработчика.

Во-первых в силу своего высокого разрешения они могут считать до более 4 миллиардов, а также у них очень широкий функционал.

Теперь мы научимся делать из предыдущего проекта следующий, чтобы заново не настраивать все в Cube и не потерять наш рукописный код в проекте Keil.

Для этого создадим папку TEST02.

Скопируем туда файлы .mxproject и TEST001.ioc

Исправим имя файла TEST001.ioc на TEST002.ioc

Внутри файлов также везде меняем TEST001 на TEST002 (получится в 5 местах).

Также копируем со старого проекта папки src и inc с содержимым. Всё!

Проект готов. Запускаем TEST002.ioc

Давайте пока воспользуемся базовыми таймерами, а вернее одним из них – таймером 6

В Cube MX ставим TIM6 -> Activated

Пройдем в мануал и посмотрим (стр. 65-66), на какой шине какой таймер находится — это APB1 и настроим ее в Clock Configuration. Здесь главное не превысить граничную частоту (42 МГц).

Давайте поставим делитель APB1 prescaler равным 8,частота получится 21 мГц, а для таймера будет 42. Нам этого вполне хватит.

Затем идем в закладку Configuration и настраиваем там таймер.

В закладке Parameter Settings выставляем следующие значения

Prescaler (PSC – 16 bit value) – 20999

Counter Period – 499

Trigger Event Selection – Update Event

В закладке NVIC Settings включаем глобальные прерывания таймера 6

Жмем Apply

Генерируем проект Keil5 таким же образом как и на прошлом занятии

Собираем проект в кейле. Открываем main.c – как видим ничего не пропало никуда.

Попробуем прошить и запустить. Удивительно. Все работает.

Далее подключаем таймер.

Откроем там раздел 61.3.3 Time Base functions

Найдем фукцию, запускающую таймер HAL_TIM_Base_Start

Вставляем код в main.c

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

Также запускаем прерывания от таймера

Для этого есть аналогичная функция HAL_TIM_Base_Start_IT

Вставляем ее сюда же

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

В файле stm32f4xx_it.c находим функцию прерывания от таймера и добавляем туда код

/* USER CODE BEGIN TIM6_DAC_IRQn 0 */

Читайте также:  Besder yoosee ip камера wi fi установка

/* USER CODE END TIM6_DAC_IRQn 0 */

/* USER CODE BEGIN TIM6_DAC_IRQn 1 */

/* USER CODE END TIM6_DAC_IRQn 1 */

Из бесконечного цикла уберем вот эту строку, чтобы не мешала работать таймеру

else HAL_GPIO_WritePin(GPIOD, PIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

Теперь попробуем разнообразить

Файл main.h из старого проекта положим в папку inc и подключим его в главном модуле main.c

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

Очистим его, оставив только директивы и добавим туда глобальную переменную

Проинициализируем ее в функции main

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

Проэкстерналим в файле stm32f4xx_it.c

/* USER CODE BEGIN 0 */

extern uint8_t tim6_counter;

/* USER CODE END 0 */

Изменим код в функции прерывания в этом же файле

/* USER CODE BEGIN TIM6_DAC_IRQn 0 */

/* USER CODE END TIM6_DAC_IRQn 0 */

/* USER CODE BEGIN TIM6_DAC_IRQn 1 */

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);

/* USER CODE END TIM6_DAC_IRQn 1 */

В файле main.c уберем запуск таймера

А в бесконечном цикле код изменим следующим образом

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

if(HAL_GPIO_ReadPin (GPIOA, GPIO_PIN_0)==GPIO_PIN_SET)

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);


Artwork by dangercook


Artwork by dangercook

HAL — это дальнейшее развитие библиотеки SPL, выпущенной фирмой "ST Microelectronics", ориентированный на то, что бы дать разработчику единый инструмент для работы со всеми чипами STM32. Этим единым инструментом стала кросс-платформенная утилита с графическим интерфейсом STM32CubeMX, а сам фреймворк HAL стал называться STM32Cube. И если утилита STM32CubeMX действительно одна для всех микроконтроллеров STM32, то фреймворк STM32Cube/HAL для каждой линейки чипов свой. Т.е. все так же как и в SPL.

STM32CubeMX — позволяет сгенерироваль проект на основе CMSIS+HAL под различные IDE, что помогает избежать многих граблей, на начальном этапе освоения STM32.

Нас будет интересовать линейка STM32F1xx, документация по HAL для этой линейке доступна на официальном сайте Description of STM32F1xx HAL drivers. User Manual UM1850 Description of STM32F1xx HAL drivers. User Manual UM1850

Установка связки STM32CubeMX + IDE в системах Windows, тривиальна и многократно описана в сети, а вот в Linux могут возникнуть сложности.

Для Eclipse существует плагин STM32Cube, который позволяет запустить STM32CubeMX в окошке Eclipse. Есть в сети пошаговая инструкция как этим плагином пользоваться: Установка и настройка Eclipse, STM32CubeMX под Windows, и я даже где-то видел видео, где все работает. Но в моем случае, проект который в итоге генерировался, Eclipse-ом почему-то не желался приниматься:

И хотя возможно, что можно было бы доконфигурировать проект Eclipce’а, лучше будет воспользоваться готовым IDE "SystemWorkbench for STM32"(он же SW4STM32) компании AC6 на базе того же Eclipse:

Читайте также:  Как делать скриншот в танках

SW4STM32 полностью бесплатный, доступный для Linux, Windows и MacOS, не содержит никаких ограничений на размер генерируемого кода. Скачать его можно c официального сайта компании AC6 http://www.ac6-tools.com/downloads/SW4STM32/

Установка STM32CubeMX под Linux тоже не доставляет труда. Процесс можно посмотреть на youtube:

Попробуем написать Blink с помощью этих двух инструментов. Целевым микроконтроллером будет STM32F103CBT6, светодиод будет на PB1, тактирование от внешнего кварца на 8 MHz. Версия java:

Запускаем STM32CubeMX и создаем новый проект:

Через выпадающие списки выбираем целевой микроконтроллер:

Во вкладке "Pinout", в пункте SYS включаем отладку по SerialWire, а в через регистры контроля и тактирования RCC устанавливаем внешний кварц — HSE. На ножке PB1 выставляем режим GPIO_Output:

Во вкладке "Clock Configuration" подключаем кварц и устанавливаем нужные делители и множитель PLLMul

Во вкладке "Configuration" устанавливаем режим GPIO для PB1:

Последний этап, через меню->Genrate Code запускаем экспорт проекта. Здесь в качестве целевой IDE указываем SW4STM32, рабочий каталог должен совпадать с рабочим каталогом SW4STM32:

При этом если STM32CubeMX был запущен впервые на данном компьютере, то перед сохранением проекта, будет закачана библиотека HAL для данной линейки микроконтроллеров. Библиотеку можно будет найти в

/STM32Cube. Так же как SPL она содержит проекты с примерами для работы с той или иной периферией:

Осталось запустить SW4STM32, и через меню->File->Import импортировать сгенерированный проект:

После чего можно попытаться собрать проект:

Если проект собрался успешно, то во вкладке Console будет соответствующий отчет:

Осталось написать саму программу. В while-цикле функции main() следует вставить код:

Осталось скомпилировать проект и прошить чип:

Работать должно без вопросов.


Иследование работы программы с помощью отладчика, называется динамическим анализом кода


Иследование работы программы с помощью отладчика, называется динамическим анализом кода

Попробуем исследовать работу программы с помощью отладчика:

Поставим точку останова на главный цикл программы:

Попробуем ткнуть наугад:

Здесь вроде все нормально, как и должно быть.

Здесь задержки формируются с помощью функции HAL_Delay. Функция использует внутренний таймер ARM — SysTick. Почитать о нем можно здесь: ARM. Учебный Курс. SysTick — Системный таймер. Это обычный 24-битный счетчик, который ничего не умеет, этакий аналог TIMER0 в AVR и TIM4 в STM4. SysTick предназначен специально для формирования задержек или как таймер планировщика в операционной системе.

Заглянем внутрь функции:

так это работает:

Теперь посмотрим, как происходит переключение светодиода:

Здесь нас будет интересовать число 0x40010c00 в r0. Можно предположить, что это адрес порта. Изучение аппнота AN3422 Application note Migration of microcontroller applications from STM32F1 to STM32L1 serie подтверждает догадку:

Структура GPIO описана в заголовочном файле stm32f103xb.h

Регистр GPIOB->BSRR в пятом столбце первой строчки, в котором записано значение 0х10. Посмотрим как он меняется:

Как видно значение регистров ODR и BSRR изменилось. Идем дальше:

Значение регистров снова сбросилось. Думаю, что здесь все понятно.

Рекомендуем к прочтению

Добавить комментарий

Ваш адрес email не будет опубликован.