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

Прерывания в STM32.
Прерывания описаны в стартап файле (startup_*.s) и stm32f10x.h (IRQn_Type).
Управляет прерываниями модуль NVIC.
Настройка прерываний:
  1. Настроить и разрешить необходимые прерывания периферии. 
  2. Разрешить глобальные прерывания.
  3. Описать обработчик прерывания.
Рассмотрим внешние прерывания. За внешние прерывания отвечает модуль EXTI (EXTernal Interrupts). Особенностью внешних прерываний STM32 является то, что их можно повесить на любую ножку, но всего можно настроить 16 прерываний, т.е. столько же, сколько линий у порта. Прерывания настраиваются на линию, а не порт, поэтому когда возникает прерывание, необходимо вручную проверять, с какого порта.
Настраиваем прерывание:
Подаем тактирование на порт и на альтернативную функцию.
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN;
GPIOA->CRL &= ~GPIO_CRL_MODE0; // Настраиваем на ввод
Ножка на кнопке подтянута к земле, поэтому CNF можно не трогать.
AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI0_PA; // Настраиваем прерывание на линию 0 порта А
EXTI->RTSR |= EXTI_RTSR_TR0; // Прерывание по восходящему фронту
NVIC_EnableIRQ(EXTI0_IRQn); // Глобально разрешаем прерывания по 0 линии
EXTI->IMR |= EXTI_IMR_MR0; // Включаем прерывание по линии 0
Все это упаковываем в функцию, например, button_init().

Далее пишем обработчик прерывания 0 линии:
void EXTI0_IRQHandler(void)
{
  // ...
}
Т.к. прерывание могло быть вызвано 0 линией любого порта, то надо удостовериться в том, что оно пришло именно от кнопки (порт А):
if((GPIOA->IDR & 1) == 1)
{ 
   // ...
}
Ждем отпускания кнопки
while((GPIOA->IDR & 1) == 1)
soft_delay(10000);
Производим какие-либо действия, например, зажигаем или гасим светодиод на ножке PC9
GPIOC->ODR ^= GPIO_ODR_ODR9;
Сбрасываем флаг прерывания путем записи "1". Иначе прерывание будет вызываться постоянно, непрерывно.
EXTI->PR |= EXTI_PR_PR0;

Когда все настроено, разрешаем глобально прерывания командой
__enable_irq ();

__enable_irq () глобально разрешает прерывания, __disable_irq() - запрещает. Аналоги на AVR - "sei" и "cli". Глобально разрешать прерывания следует после того, как будет проинициализирована вся периферия и все подключенные устройства, иначе что-то может не завестись, например, из-за неправильной задержки.
В прерываниях следует выполнять задачи как можно быстрее, сводя их к минимуму, например, устанавливая флаги, а обрабатывая в основном цикле, дабы свести время пребывания в прерывании к минимуму.

Файл проекта - https://drive.google.com/open?id=1hXe5bhdP-rQOyKccpZ2icx0A8tSaZ8_4

Комментарии

Популярные сообщения из этого блога

STM32. Часть 4. Задержки, таймеры, системный таймер SysTick

AVR. Assembler. Алгоритмы.

STM32. Создание проекта в Keil.