Организация прерываний на STM32 без лишних хлопот

Группа компаний Промэлектроника
30.08.2012
Прерывание – важная функция микроконтроллера. Благодаря ей он может практически без задержек выполнять задачи высокой важности на фоне остальных, менее значимых задач. Сегодня мы расскажем, как правильно организовать прерывания в контроллерах семейства STM32.
Для организации векторов прерываний будем использовать стандартные средства, включая библиотеку стандартных функций, написанную инженерами STMicroelectronics. В качестве среды берём IAR.
В первую очередь после создания проекта нам необходимо включить в его состав файл startup с расширением S. Находится он в стандартной библиотеке. Для каждой среды он имеет свой вид. Мы рассматриваем в качестве среды IAR.



 
Заходим в соответствующую папку и видим один или несколько файлов sturtupXXXXXX.s. Несколько файлов может быть по причине наличия подсемейств в семействе.

Например, семейство STM32F1 имеет 8 подсемейств:
  • Connectivity Line 105/107 процессоры (startup_stm32f10x_cl.s)
  • Процессоры линеек 101 – 103 с флэш памятью от выше 512 кб (startup_stm32f10x_xl.s)
  • Процессоры линеек 101 – 103 с флэш памятью от 256 до 512 кб (startup_stm32f10x_hd.s)
  • Процессоры линеек 101 – 103 с флэш памятью от 64 до 128 кб (startup_stm32f10x_md.s)
  • Процессоры линеек 101-103 с флэш памятью до 32 кб (startup_stm32f10x_ld.s)
  • Процессоры 100 линейки с флэш памятью до 32 кб (startup_stm32f10x_ld_vl.s)
  • Процессоры 100 линейки  с флэш памятью выше 32 кб (startup_stm32f10x_md_vl.s)
  • Процессоры 100 линеки с флэш памятью от 256 до 512 кб (startup_stm32f10x_hd_vl.s)

Что записано в этих файлах? Открыть можно любой из них «блокнотом» или сразу в среде разработки. Главным образом, здесь записаны вектора прерываний. Вот, например, прерывание сброса (первое в списке):

Reset_Handler
LDR     R0, =SystemInit
BLX     R0
LDR     R0, =__iar_program_start
BX      R0


Отсюда мы делаем вывод, что, подключив файл startupXXXXX.s, после сброса  контроллер осуществит переход в функцию SystemInit() и только потом в тело основной программы. Функция SystemInit() находится в файле system_stm32f10x.c (для других семейств – файл имеет схожее название). Данная функция отвечает за перевод контроллера на внешнее тактирование (если оно есть) и инициализацию контроллера внешней памяти (если это требуется). Если мы хотим использовать эту функцию, требуется подключение файла system_stm32f10x.c (или схожего для других семейств) в проект. Если мы не хотим использовать эту функцию, то требуется заменить первую строку третьей на представленном листинге.

Какая ещё важная информация для разработчика имеется в файле sturtupXXXXX.s? Безусловно, это название функций прерываний. Т.е., если название какой-либо функции проекта разработчика совпадёт с функцией, находящейся в этом файле, то она будет ассоциирована как описание конкретного прерывания. Именно из этого файла компилятор узнаёт какая процедура является прерыванием, а какая – нет. Например, если мы хотим получить прерывание от Таймера2, то каким образом должна называться процедура-обработчик?
Ищем в файле startup название и находим «TIM2_IRQHandler». Если мы введём в своём проекте функцию TIM2_IRQHandler и опишем её, то в случае поступления запроса на прерывание от таймера2 программа осуществит переход в эту процедуру.                

Итак, часть необходимых подключений выполнена. Остаётся 2 пункта:
  • Установить приоритет и разрешить контроллеру прерываний NVIC обрабатывать прерывания от конкретной периферии
  • Разрешить периферии генерировать прерывания

Мы не будем говорить подробно о «переменной вложенности» прерываний, просто отметим, что по желанию программиста можно настроить контроллер прерываний NVIC так, что прерывания в зависимости от приоритета смогут или не смогут прерывать друг друга (интересующимся деталями рекомендуем Мануал на контроллер).

На примере TIM2 разрешаем прерывания:

// переменная описывающая функцию контроллера прерываний
NVIC_InitTypeDef NVIC_InitStructure;
// задаём вложенность (читать мануалJ )
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

// разрешаем прерывание от таймера 2

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);


Откуда мы взяли значение свойства NVIC_InitStructure.NVIC_IRQChannel  (=TIM2_IRQn)? Где взять значение этого свойства для других прерываний? Ответ – в файле «stm32f10x.h» (или со сходным названием для других семейств STM32). Файл внутри стандартной библиотеки.
Теперь контроллер при получении сигнала запуска прерывания будет запускать процедуру «TIM2_IRQHandler». Осталось заставить работающую периферию генерировать прерывания. В данном случае TIM2.

Средствами стандартной библиотеки это делается так:

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

При переполнении таймера будет выполняться прерывание «TIM2_IRQHandler». Подробное описание функций (включая их исходники и примеры) – в описании библиотек, в файле «stm32f10x_stdperiph_lib_um.chm» (или со сходным названием для других семейств)

PS. Далее следует скриншот рабочего проекта, в котором были использованы прерывания. На нём отмечены файлы, которые необходимо подключить в свой проект для организации прерываний.



 
Из всех выделенных файлов не было сказано ничего о «misc.c». Этот файл описывает все стандартные функции контроллера внешних прерываний. Например,

NVIC_Init(&NVIC_InitStructure),


которая фигурирует выше по тексту.

За получением более подробной информации вы можете обратиться:

Бренд-менеджер:
Сорокин Сергей
E-mail: info@promelec.ru
Телефон: +7 (343) 245-68-20

Задать вопрос техподдержке вы можете на нашем форуме.


  "ПРОМЭЛЕКТРОНИКА" - официальный прямой дистрибьютор компании "STMicroelectronics"


Последние новости - одной лентой: