|
Не срабатывает внешнее прерывание |
|
|
|
Dec 2 2014, 19:46
|
Знающий
   
Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231

|
Всем привет. Столкнулся с такой проблемой в STM32F407: Если сделать критическую секцию для внешнего прерывания, то если его отключить на время выполнения кода, а потом опять включить, но за время выполнения кода пришло внешнее прерывание, то при последующем включении внешнего прерывания, прерывание не сработает. Т.е. получается будет пропущенное прерывание на время его отключения. Как сделать чтобы при включении внешнего прерывания его сработавший флаг был активен? Код инициализации CODE #define TEST_IRQ_PIN GPIO_Pin_14 #define TEST_IRQ_GPIO_PORT GPIOE #define TEST_EXTI_Line EXTI_Line14 #define TEST_IRQChannel EXTI15_10_IRQn #define TEST_EXTI_PortSource EXTI_PortSourceGPIOE #define TEST_GPIO_PinSource GPIO_PinSource14
// отключение обработки внешнего прерывания #define ENTER_NOIRQ_REGION() { ITStatus exti_status = EXTI_GetIRQStatus(TEST_EXTI_Line); \ EXTI_Disable_IRQ(TEST_EXTI_Line); \
// включение обработки прерывания #define LEAVE_NOIRQ_REGION() if(exti_status != RESET) \ EXTI_Enable_IRQ(TEST_EXTI_Line); \ }
GPIO_InitStructure.GPIO_Pin = TEST_IRQ_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(TEST_IRQ_GPIO_PORT, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); SYSCFG_EXTILineConfig(TEST_EXTI_PortSource, TEST_GPIO_PinSource);
EXTI_InitStructure.EXTI_Line = TEST_EXTI_Line; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TEST_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); Такой вид имеет код приложения Код ENTER_NOIRQ_REGION(); ... Копирование данных ... LEAVE_NOIRQ_REGION();
Сообщение отредактировал IgorKossak - Dec 2 2014, 19:55
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Dec 3 2014, 10:34
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Rash @ Dec 2 2014, 22:46)  Т.е. получается будет пропущенное прерывание на время его отключения. Если взглянуть на блок-схему EXTI, то ровно так оно и должно работать: регистр маскирования не пропускает сигнал со входа в регистр Pending Request. Цитата(Rash @ Dec 2 2014, 22:46)  Как сделать чтобы при включении внешнего прерывания его сработавший флаг был активен? Опять же, если взглянуть на блок схему, то напрашивается вывод, что прерывание надо маскировать на уровне NVIC. Другие способы не просматриваются.
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 3 2014, 17:20
|
Знающий
   
Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231

|
Я понял, спасибо за разъяснение. Но если работать через NVIC, то получается если запретить EXTI15_10_IRQn, то не работать будут сразу 5 прерываний объединённых в эту группу. Не критично конечно, но не приятно, нужно на будущее учесть. В STM с внешними прерываниями какая то урезанность, например: на два одинаковых бита различных портов нельзя сделать прерывания (PA2 и PB2). Ещё такой вопрос если мне нужно определить включено ли сейчас прерывание, нужно читать регистр ISER или также можно ISPR? т.е. мне нужно прочитать состояние прерывания, запомнить его, выполнить операцию и вернуть обратно статус.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|