реклама на сайте
подробности

 
 
> STM32F407 внешние прерывания на линии 5_9
Mister_DSP
сообщение Dec 17 2016, 09:38
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 133
Регистрация: 5-11-16
Пользователь №: 94 050



Доброе время суток!

Так уж получилось, что приходится использовать Port C8 для ножки внешнего прерывания с устройства.
Я чуть не пророс, когда увидел, что порты с номерами 5,6,7,8,9 объединены в один обработчик прерывания - в Keil это функция EXTI9_5_IRQHandler().
Ранее на макете были линии 0 и 4 (на них линии и обработчики прерываний по-отдельности и о подвохах не догадывался).

Пока код использую такой (он рабочий).

Инициализация(здесь в тексте много опущено для упрощения):
CODE
GPIO_InitTypeDef gpio;
EXTI_InitTypeDef exti;
NVIC_InitTypeDef nvic;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);

GPIO_StructInit(&gpio);

//INPUT
//C8=>IRQ !!!
gpio.GPIO_Pin=GPIO_Pin_8;
gpio.GPIO_Mode=GPIO_Mode_IN;
gpio.GPIO_Speed=GPIO_Speed_25MHz; //!!!
gpio.GPIO_OType=GPIO_OType_PP;
gpio.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC,&gpio);

//IRQ C8
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,EXTI_PinSource8);

exti.EXTI_Line=EXTI_Line8;
exti.EXTI_LineCmd=ENABLE;
exti.EXTI_Mode=EXTI_Mode_Interrupt;
exti.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_Init(&exti);

nvic.NVIC_IRQChannel=EXTI9_5_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority=0;
nvic.NVIC_IRQChannelSubPriority=0;
nvic.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&nvic);


Сам обработчик:
Код
void EXTI9_5_IRQHandler()
{
if(EXTI_GetITStatus(EXTI_Line8)!=RESET) //Make sure that interrupt flag is set
{

  //Тут код полезной нагрузки.......


  EXTI_ClearITPendingBit(EXTI_Line8); //Clear interrupt flag
  
  return; //для надёжности - на одном сайте говорили что лучше так принудительно выходить :)
}
}


За CMSIS и SPL не пинайте, так как не являюсь фанатом КУБа и его HAL.

Вопрос вот в чём:
Я использую одну из ножек порта C - линию 8 для прерывания (настроена на ввод). Этот же порт C я использую для аппаратного SPI + ещё другие линии отдельно как GPIO на вывод.

Можно ли в обработчике не делать проверку:
Код
if(EXTI_GetITStatus(EXTI_Line8)!=RESET)......


а сразу приступать к полезной нагрузке? При условии что более нет прерываний на C5,6,7,9 ? И линия 8 также не используется по прерываниям.

И когда правильнее сбрасывать бит прерывания - ДО или ПОСЛЕ полезной нагрузки?
Код
EXTI_ClearITPendingBit(EXTI_Line8); //Clear interrupt flag


Сообщение отредактировал IgorKossak - Dec 17 2016, 12:14
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!


--------------------
SPY vs. SPY
Хорошо там, где нет ничего...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 8)
hd44780
сообщение Dec 17 2016, 12:45
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Цитата(Mister_DSP @ Dec 17 2016, 12:38) *
Можно ли в обработчике не делать проверку:
Код
if(EXTI_GetITStatus(EXTI_Line8)!=RESET)......


а сразу приступать к полезной нагрузке? При условии что более нет прерываний на C5,6,7,9 ? И линия 8 также не используется по прерываниям.

Насколько я понимаю - да. но если Вы добавите 5,6,7 или 9 - условия понадобятся.

Цитата(Mister_DSP @ Dec 17 2016, 12:38) *
И когда правильнее сбрасывать бит прерывания - ДО или ПОСЛЕ полезной нагрузки?
Код
EXTI_ClearITPendingBit(EXTI_Line8); //Clear interrupt flag

Моё ИМХО - после нагрузки.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
EugenPKH
сообщение Dec 17 2016, 13:30
Сообщение #3





Группа: Новичок
Сообщений: 4
Регистрация: 6-07-16
Пользователь №: 92 447



Цитата(hd44780 @ Dec 17 2016, 12:45) *
Насколько я понимаю - да. но если Вы добавите 5,6,7 или 9 - условия понадобятся.


Моё ИМХО - после нагрузки.


Не знаю как в данной библиотек ( SPL ,HAL ) но если на CMSIS то надо До, Если поставить после, то может не сбросится прерывание и будет повторный заход , чтоб этого не произошло надо еще барьер ставить тогда.
Go to the top of the page
 
+Quote Post
Mister_DSP
сообщение Dec 17 2016, 13:45
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 133
Регистрация: 5-11-16
Пользователь №: 94 050



Спасибо за внимание.

Сделал как hd44780 написал - работает, глюки пока не обнаружены.

EugenPKH, прерывание по перепаду состояния, а не по уровню. Там же ТАКЖЕ сбрасывается бит ВНЕШНЕГО устройства. Так что при любом желании, оно повторно не выскочет.

Вот зато есть такая особенность: при включении питания прерывание срабатывает сразу в первый раз!
Приходится программно игнорировать первое вхождение:

CODE

static char f=0;
if(!f)f=1;
else
{
//...делаем полезное...
}


При этом порты инициализируются раньше, чем разрешаются прерывание.
И такое на AVR-ках тоже было.

Как можно это устранить?

Сообщение отредактировал Mister_DSP - Dec 17 2016, 13:47


--------------------
SPY vs. SPY
Хорошо там, где нет ничего...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 17 2016, 13:51
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Пока вы не разрешите прерывания от ног 5-7, 9 в регистре EXTI->IMR, они не будут выставлять свои флаги и не будут вызывать прерывание. Как это делается в SPL или кубах - понятия не имею. В обычной жизни для этого достаточно одной строки записи в регистр.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Mister_DSP
сообщение Dec 17 2016, 14:01
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 133
Регистрация: 5-11-16
Пользователь №: 94 050



Цитата(Сергей Борщ @ Dec 17 2016, 14:51) *
Пока вы не разрешите прерывания от ног 5-7, 9 в регистре EXTI->IMR, они не будут выставлять свои флаги и не будут вызывать прерывание. Как это делается в SPL или кубах - понятия не имею. В обычной жизни для этого достаточно одной строки записи в регистр.

Так речь идет о том, что как раз я и разрешаю прерывание и оно в первый раз случается без воздействия внешнего устройства (источника прерывания).
Подозреваю, что такое поведение возникает из-за запоминания контроллером состояния перепада уровня при настройке портов.
А вот со второго раза и далее - прерывания уже идут в тему - от устройства.


--------------------
SPY vs. SPY
Хорошо там, где нет ничего...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 17 2016, 17:25
Сообщение #7


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Так вы его очистите, прежде, чем разрешать.
Go to the top of the page
 
+Quote Post
EugenPKH
сообщение Dec 17 2016, 17:39
Сообщение #8





Группа: Новичок
Сообщений: 4
Регистрация: 6-07-16
Пользователь №: 92 447



Цитата(Mister_DSP @ Dec 17 2016, 14:45) *
EugenPKH, прерывание по перепаду состояния, а не по уровню. Там же ТАКЖЕ сбрасывается бит ВНЕШНЕГО устройства. Так что при любом желании, оно повторно не выскочет.

При этом порты инициализируются раньше, чем разрешаются прерывание.
И такое на AVR-ках тоже было.

Как можно это устранить?



Если будете сбрасывать прерывания не через библиотеку, а напрямую(EXTI->PR = EXTI_PR_PR8;) увидите двойной вхождения скорее всего. Второе вхождения происходит из-за того что не успевает флаг сбросится , а не потому что его кто то вызвал.

Чтоб убрать первое вхождение в прерывания при запуске - на просто перед разрешением прерывания сбросить флаг
EXTI->PR = EXTI_PR_PR8; Как через библиотеку не знаю.



Go to the top of the page
 
+Quote Post
Mister_DSP
сообщение Dec 18 2016, 07:03
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 133
Регистрация: 5-11-16
Пользователь №: 94 050



всем спасибо.

помогла очистка флага перед разрешением прерывания: EXTI_ClearITPendingBit(EXTI_Line8);


--------------------
SPY vs. SPY
Хорошо там, где нет ничего...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 04:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01427 секунд с 7
ELECTRONIX ©2004-2016