STM32F030F4P6 прерывания

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
andrey_spb
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вс фев 08, 2015 22:00:13

STM32F030F4P6 прерывания

Сообщение andrey_spb »

Спаял на днях тестовую платку на вышеуказанном камне и начал потихоньку ее мучать. GPIO прошло на ура, все мигало и откликалось на нажатие кнопок.
Перешел к прерываниям. Решил настроить EXTI для кнопки, подключенной к PB1. Как водится, читал статьи по этому вопросу и изучал код из примеров.
Но прерывания не заводились.
Читал вот это:http://www.hertaville.com/external-inte ... m32f0.html
Код инициализации у автора такой
Спойлер

Код: Выделить всё

SYSCFG->EXTICR1  &= (0x000F) ;
  //1. clear bits 3:0 in the SYSCFG_EXTICR1 reg to amp EXTI Line to NVIC

  EXTI->RTSR = EXTI_RTSR_TR0;
  // 2.Set interrupt trigger to rising edge

  EXTI->IMR = EXTI_IMR_MR0; // 3. unmask EXTI0 line
  NVIC_SetPriority(EXTI0_1_IRQn, 1); //4. Set Priority to 1
  NVIC_EnableIRQ(EXTI0_1_IRQn);  // 5. Enable EXTI0_1 interrupt in NVIC (do 4 first)
Скачал сниппеты, там вот так выглядит
Спойлер

Код: Выделить всё

__INLINE void  ConfigureExternalIT(void)
{  
  /* (1) Enable the peripheral clock of GPIOA */ 
  /* (2) Select Port A for pin 0 external interrupt by writing 0000 in EXTI0 (reset value)*/
  /* (3) Configure the corresponding mask bit in the EXTI_IMR register */
  /* (4) Configure the Trigger Selection bits of the Interrupt line on rising edge*/
  /* (5) Configure the Trigger Selection bits of the Interrupt line on falling edge*/
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* (1) */
  //SYSCFG->EXTICR[1] &= (uint16_t)~SYSCFG_EXTICR1_EXTI0_PA; /* (2) */
  EXTI->IMR = 0x0001; /* (3) */ 
  EXTI->RTSR = 0x0001; /* (4) */
  EXTI->FTSR = 0x0001; /* (5) */
  
  /* Configure NVIC for External Interrupt */
  /* (6) Enable Interrupt on EXTI0_1 */
  /* (7) Set priority for EXTI0_1 */
  NVIC_EnableIRQ(EXTI0_1_IRQn); /* (6) */
  NVIC_SetPriority(EXTI0_1_IRQn,0); /* (7) */
}
Но мой код, сделанный по аналогии, вот такой, не работал:

Код: Выделить всё

SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI1_PB; 
EXTI->IMR = EXTI_IMR_MR1;//демаскируем прервание по 1 линии
EXTI->FTSR = EXTI_FTSR_TR1; //прерывание по спаду
EXTI->RTSR = EXTI_RTSR_TR1; //прерывание по фронту  
NVIC_EnableIRQ(EXTI0_1_IRQn);
NVIC_SetPriority(EXTI0_1_IRQn,0);
Благо наткнулся на статью
http://easyelectronics.ru/arm-uchebnyj- ... aniya.html
Там:
Но после выяснилось, что без включения AFIO мультиплексоры не работают. Т.е. сигнал будет передаваться ТОЛЬКО от порта А, т.к. это дефолтное значение мультиплексоров.
В моем камне не AFIO , обзывается регистр по другому. Сделал по аналогии.
Добавил в начало инициализации

Код: Выделить всё

RCC->APB2ENR |=RCC_APB2ENR_SYSCFGCOMPEN;// тактирование SYSCFG 
И прерывания начали прерывать.
В общем, может пригодится начинающим.
Последний раз редактировалось andrey_spb Вс янв 24, 2016 14:05:26, всего редактировалось 1 раз.
Реклама
andrey_spb
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вс фев 08, 2015 22:00:13

Re: STM32F030F4P6 прерывания

Сообщение andrey_spb »

По прерываниям вопросы.
Мы сбрасываем флаг в обработчике

Код: Выделить всё

EXTI->PR |= EXTI_PR_PR1;
Записываем единицу в нужный бит. Но там ведь уже единица? Не понял смысл
У меня например проверяется прерывание с линии 1 вот так:

Код: Выделить всё

if (EXTI->PR & EXTI_PR_PR1)
Поскольку в моем камне обработчик на две линии 0 и 1, EXTI0_1_IRQHandler.

Еще в вышеуказанной мной статье автор утверждает что:
The next step is to enable the interrupt in the NVIC (Note that its very important to set the interrupt priority before you enable the interrupt). One can do this by setting bit 5 of the NVIC_ISER register. Or alternatively use the CMSIS function "NVIC_EnableIRQ()" which takes the interrupt source position in the table in Figure 1 as a parameter. In our case that's "EXTI0_1_IRQn" or 5.
То есть приоритет нужно установить до включения прерываний. А в сниппетах наоборот

Код: Выделить всё

NVIC_EnableIRQ(EXTI0_1_IRQn); /* (6) */
NVIC_SetPriority(EXTI0_1_IRQn,0); /* (7) */
Как правильно?
Реклама
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: STM32F030F4P6 прерывания

Сообщение oleg110592 »

Не понял смысл
из документации:
PRx: Pending bit on line x
This bit is set when the selected edge event arrives on the external interrupt line.
This bit is cleared by writing a 1 to the bit.

тактирование SYSCFG после настройки SYSCFG->EXTICR можно сразу выключить (для экономии :) ):
RCC->APB2ENR |=RCC_APB2ENR_SYSCFGCOMPEN;// тактирование SYSCFG
SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI1_PB;
RCC->APB2ENR &= ~RCC_APB2ENR_SYSCFGCOMPEN;

приоритет, имхо, все равно в какой последовательности устанавливать - если прерывания появятся во время настройки (наверное это не желательно) ну пусть несколько раз сработают с неправильным приоритетом, потом все нормализуется. В документации (в примере) так же сделано как и в снипетсах.
andrey_spb
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вс фев 08, 2015 22:00:13

Re: STM32F030F4P6 прерывания

Сообщение andrey_spb »

oleg110592 писал(а):
Не понял смысл
из документации:
PRx: Pending bit on line x
This bit is set when the selected edge event arrives on the external interrupt line.
This bit is cleared by writing a 1 to the bit.
И?
"Этот бит устанавливается при событии на выбранной линии. Этот бит очищается записью 1 в этот бит."
Именно это я не понял. И даже если еще сто раз скопипастить английский текст из документации, вряд ли пойму.
Я не понял следующее: при прерывании бит устанавливается, то есть там единица. И очищаем его записью единицы. Смысл писать единицу в бит, если она там уже?
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: STM32F030F4P6 прерывания

Сообщение oleg110592 »

andrey_spb писал(а):И даже если еще сто раз скопипастить английский текст из документации, вряд ли пойму
тут, имхо, надо просто принять как должное - просто так сделал производитель микроконтроллера (для примера - в логических схемах триггеры можно было сбрасывать подачей лог. "1" на вход сброса).
Наверное еще более удивит, если придется заниматься USART в STM32, это:
Bit 5 RXNE: Read data register not empty
This bit is set by hardware when the content of the RDR shift register has been transferred to the USARTx_RDR register. It is cleared by a read to the USARTx_RDR register.
Бит RXNE регистра USARTx_ISR сбрасывается при чтении совершенно другого регистра USARTx_RDR - тут вообще никуда не надо записывать ни "0" ни "1" достаточно прочитать данные из приемного регистра, что вполне логично - все равно данные нужны для дальнейшей обработки.
Реклама
Ответить

Вернуться в «ARM»