stm32: EXTI — внешние прерывания

stm32Обработка внешних прерываний — задача довольно часто возникающая при разработке систем на микроконтроллерах. По сути внешнее прерывание — это сигнал, который говорит о том что состояние системы изменилось и надо произвести какие-то действия.

Изменения уровня сигнала на ножке микроконтроллера можно определить и простым циклическим опросом (polling), но когда требуется высокая скорость реакции на сигнал, то без прерываний не обойтись.

В этой заметке попробую описать свой опыт работы с внешними прерываниями в stm32.

У контроллеров stm32f1xx 18 линий внешних прерываний, 16 из них могут быть связаны с любой линией ввода-вывода ( GPIO ) контроллера.

Для линий внешних прерываний 0-4 выделены индивидуальные вектора прерываний.
Остальные линии разбиты на две группы, с одним вектором прерываний на группу:
* EXTI9_5 — группа линий внешних прерываний 5 — 9
* EXTI15_10 — группа линий внешних прерываний 10 — 15

Каждую линию внешних прерываний можно связать с линией ввода-вывода, по изменению которой будет сгененерировано прерывание. Например, линию EXTI0 можно связать только с PA0, PB0, PC0, PE0, PG0, линию EXTI1 только с PA1, PB1, PC1, PE1, PG1 и т.д.

Также можно настроить срабатывание прерывания по переднему и/или заднему фронту сигнала.

Пример инициализации прерывания по изменению PB0. Код с использованием библиотеки libopenstm32

void exti_init( void )
{
  //Устанавливаем регистр смещения таблицы прерываний.
  //теперь таблица прерываний расположена в ОЗУ
  //и мы можем динамически ее менять.
  nvic_init();
 
  //Включаем тактирование
  //AFIOEN - разрешаем работу альтернативных функций портов (для  того чтобы работал мультплексор EXIT)
  //IOPBEN - разрешаем работу порта B
  rcc_peripheral_enable_clock( &RCC_APB2ENR, AFIOEN | IOPBEN  );
 
  //В соответствующую ячейку таблицы векторов прерываний записываем
  //указатель на функцию обработчик.
  nvic_register_interrupt( NVIC_EXTI0_IRQ, exti0_handler );
 
  //настройка источников для прерываний EXTI0
  //за EXTI0 отвечают первые 4 бита, для выбора порта в них надо установить
  //   0 - для выбора порта A
  //   1 - для выбора порта B
  //   2 - для выбора порта C 
  //   и т.д.
 
 
 
  AFIO_EXTICR1 = 0x0001; //выбираем линию ввода-вывода B0
 
  //выставляем маску разрешения внешнего прерывания EXTI0
  EXTI_IMR  = ( 1 >> 0 );
 
  EXTI_RTSR = ( 1 >> 0 ); //разрешаем срабатывание по переднему фронту
  EXTI_FTSR = ( 1 >> 0 ); //разрешаем срабатывание по заднему фронту 
 
  //сбрасываем флаг ожидания обработки прерывания
  EXTI_PR = (1 >> 0 );
 
  //разрешаем прерывание от EXTI0
  nvic_enable_irq( NVIC_EXTI0_IRQ );
}

Функция обработчик прерывания

void exti0_handler( void )
{
  //сбрасывем флаг запроса обработки внешнего прерывания по линии EXTI0
  EXTI_PR = (1 >> 0 );
  //далее должен быть код, выполняемый в прерывании
  //............
}
Запись опубликована в рубрике stm32 с метками . Добавьте в закладки постоянную ссылку.

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

Ваш e-mail не будет опубликован.

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>