CUSTOMELECTRONICS.RU
Информационно-учебный блог о разработке электроники
Эл. почта: info@customelectronics.ru

STM32. Прерывания

В этой статье мы поделимся базовыми знаниями о практической реализации механизма прерываний от различных источников в этих микроконтроллерах. В частности будут рассмотрены прерывания от кнопки и по таймеру, а также создание внешних переменных. Напомню, что наш курс сквозной и мы рассчитываем при написании этой статьи, что читатель ознакомился с предыдущими статьями.

Внешние прерывания

Ранее мы рассматривали подключение кнопки к выводу контроллера и опрос ее состояния в основном цикле. Такая реализация часто встречается на практике, но в некоторых случаях удобнее использовать прерывания.
Для начала создадим проект в CubeMX. Необходимо запустить его и выбрать используемую вами отладочную плату. В нашем случае это Nucleo64 на контроллере STM32F030R8T6. Подготовка проекта была описана в предыдущих статьях.
Если посмотреть в параметрах преднастроенного проекта, то можно увидеть, что голубая кнопка, подключенная к выводу PC13, уже настроена в режиме прерываний.
1
Чтобы это прерывание начало срабатывать, необходимо включить его. Для этого перейдите во вкладку "Configuration" и в меню "NVIC" установите галочку "EXTI line 4 to 15 interrupts". Обратите внимание, что это прерывание генерируется одно на несколько каналов. Это означает, что если надо подключить несколько кнопок, то и в обработчике прерывания потом придется опрашивать эти кнопки, чтобы выяснить какая из них конкретно была нажата.
2
Также обратите внимание, что в пункте меню "GPIO" можно установить режим работы прерывания. По умолчанию установлено "External Interrupt Mode with Falling edge trigger detection", то есть прерывание генерируется по спаду.
3
На этом предварительная настройка окончена. Можно сгенерировать проект и приступить к написанию кода.
После запуска Keil uVision в папке "Application/User" необходимо найти файл "stm32f0xx_it.c". Это файл в котором уже сгенерированы обработчики различных прерываний. Нас интересует обработчик EXTI4_15_IRQHandler.
4
В обработчике этого прерывания мы вызовем функцию HAL_GPIO_TogglePin(). Она изменяет состояние вывода на противоположное. На плате Nucleo есть светодиод, подключенный к выводу PA5. Если мы скомпилируем и загрузим этот проект, то кнопка начнет переключать состояние светодиода на противоположное.
5
В результате проделанной работы мы получили то, что микроконтроллер в основном цикле не делает ничего, но при нажатие кнопки запускается подпрограмма, которая выполняет определенные действия.

Прерывания от таймера

Ранее мы рассматривали как организовать мигание светодиоды в основном цикле. Мы делали это самым простым способом, основная проблема которого в том, что программа почти все время остановлена вызовом функции HAL_Delay().
С другой стороны в микроконтроллерах есть таймеры, которые могут самостоятельно генерировать прерывания и выполнять какие-то действия. При этом основная программа будет останавливаться только на время, необходимое для выполнения команд обработчика прерываний. Мы рассмотрим самый простой пример работы таймера, когда он генерирует прерывания через равные интервалы времени.
В первую очередь требуется включить таймер. Для этого в CubeMX во вкладке "Pinout" включите таймер. Для примера мы включили 14ый таймер.
6
Во вкладке "Clock Configuration" можно изменить или просто проверить тактовую частоту таймера. У нас установлена тактовая частота 48МГц.
7
Затем переходим на вкладку "Configuration" и в меню "TIM14" настраиваем таймер. Делитель "Prescaler (PSC — 16 bits value)" мы установили на 47999. То есть тактовая частота таймера 48МГц будет делиться в 48000 раз (так как счет идет от нуля) и прибавление внутреннего счетчика таймера будет происходить раз в одну миллисекунду. В пункте "Counter Period" устанавливается значение счетчика, при котором генерируется прерывание и счет начинается заново. Мы хотим, чтобы светодиод изменял свое состояние раз в секунду, поэтому установили значение 999. Таймер будет с периодичностью в 1мс считать от 0 до 999, то есть прерывание будет вызываться каждую тысячу миллисекунд.
8
Также на вкладке таймера "NVIC Settings" надо установить галочку, разрешающую глобальные прерывания от таймера.
9
Обратите внимание, что в сводной таблице таймеров "NVIC" также появилась новая строка с таймером и прерывания от него включены.
10
Генерируем проект заново и открываем файл main.c. В нем нам потребуется в ручную запустить таймер в нужном нам режиме. Делается это командой HAL_TIM_Base_Start_IT(&htim14);. IT подразумевает запуск таймера в режиме прерываний. Указатель &htim14 передает функции структуру данных, в которой описаны настройки таймеров. Она генерируется автоматически CubeMX’ом.
Обратите внимание, что функция HAL_TIM_Base_Start_IT(&htim14); вызывается до вхождения в бесконечный цикл.
11
Далее снова переходим в файл "stm32f0xx_it.c" и в обработчике прерывания TIM14_IRQHandler добавляем код, изменяющий состояние вывода.
12
После компиляции и загрузки светодиод начнет мигать раз в секунду. И снова, благодаря использованию прерываний, у нас полностью разгружен основной цикл и светодиод мигает в фоновом процессе.

Внешние переменные

На практике очень часто в прерывании возникает необходимость изменять переменные, которые используются в основном цикле. То есть обращаться к переменным, описанным в другом файле.
Для примера запустим мигание светодиодом в основном цикле с переменной частотой, а частоту будем изменять в прерывании от кнопки.
Начнем с создания переменной в файле main.c.
13
Далее закомментируем функцию запуска таймера в 96ой строке и добавим код, мигающий светодиодом:
14
Если мы сейчас скомпилируем и загрузим эту программу, то светодиод начнет мигать с периодичностью 200мс. Но мы хотим изменять эту периодичность при помощи кнопки.
Поэтому переходим в файл stm32f0xx_it.c и создаем в нем внешнюю переменную extern uint16_t pause;. Служебное слово extern расширяет область видимости переменной. Важно то, что переменная инициализируется, но не определяется. То есть ей не присваивается никакое значение.
15
Осталось только добавить изменение этой переменной в прерывании. В строках 103, 104 мы просто прибавляем 100, если переменная меньше тысячи и присваиваем значение, если она равна тысяче.
16
Скомпилированная программа при старте будет мигать светодиодом быстро, а при нажатии кнопки будет изменять частоту мигания светодиодом.

Мы разобрали самые простые варианты прерываний, но даже они очень эффективные и будут использоваться нами в будущих статьях. Ссылки на остальные статьи цикла можно найти здесь.
Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.

Метки: , , , , , , Просмотров: 15669

File not found.