STM32F4 прерывание работает только в отладчике

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Встал на лапы
Аватара пользователя
Сообщения: 140
Зарегистрирован: Вт авг 03, 2010 15:21:20
Откуда: Екатеринбург

Сообщение zvukovik »

пытаюсь запустить прерывания от таймеров 2,3,4,5, для теста решил помигать диодами, делаю пошагово отладку и всё мигает как надо, а без отладки прерывание срабатывает 1 раз и на этом всё, подскажите, в чём может быть проблема...
провожу кусок кода

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

void TIM_Config(void)
{
  RCC->APB1ENR|=RCC_APB1ENR_TIM2EN|RCC_APB1ENR_TIM3EN|RCC_APB1ENR_TIM4EN|RCC_APB1ENR_TIM5EN|RCC_APB1ENR_TIM2EN|RCC_APB1ENR_TIM6EN|RCC_APB1ENR_TIM7EN;
  RCC->APB2ENR|=RCC_APB2ENR_TIM9EN;
  TIM2->ARR=20000;
  TIM2->PSC=8400-1;

  TIM2->DIER=0x00000001;
  TIM2->CR2=0x00000020;
  TIM2->CR1=0x00000085;
  
  TIM3->ARR=20000;
  TIM3->PSC=8400-1;

  TIM3->DIER=0x00000001;
  TIM3->CR2=0x00000020;
  TIM3->CR1=0x00000085;
  
  TIM4->ARR=20000;
  TIM4->PSC=8400-1;

  TIM4->DIER=0x00000001;
  TIM4->CR2=0x00000020;
  TIM4->CR1=0x00000085;
  
  TIM5->ARR=20000;
  TIM5->PSC=8400-1;

  TIM5->DIER=0x00000001;
  TIM5->CR2=0x00000020;
  TIM5->CR1=0x00000085;
  
  TIM6->ARR=10;
  TIM6->PSC=8400-1;

  TIM6->DIER=0x00000001;
  TIM6->CR2=0x00000020;
  TIM6->CR1=0x00000085;

  TIM7->ARR=50;
  TIM7->PSC=840-1;

  TIM7->DIER=0x00000001;
  TIM7->CR2=0x00000020;
  TIM7->CR1=0x00000085;
  
  TIM9->ARR=20000;
  TIM9->PSC=8400-1;

  TIM9->DIER=0x00000001;
  TIM9->CR2=0x00000020;
  TIM9->CR1=0x00000085;
}
void NVIC_Config(void)
{
  SetIrq(TIM2_IRQn,2);
  SetIrq(TIM3_IRQn,2);
  SetIrq(TIM4_IRQn,2);
  SetIrq(TIM5_IRQn,2);
  SetIrq(TIM1_BRK_TIM9_IRQn,5);
  SetIrq(TIM6_DAC_IRQn,3);
  SetIrq(TIM7_IRQn,4);
  SetIrq(USART3_IRQn,1);
}
void SetIrq(uint32_t irqn, uint32_t prio)
{
     NVIC->IP[irqn] = (prio&0x0F)<<4;
     NVIC->ISER[(uint32_t)((int32_t)irqn)>>5]=(uint32_t)(1<<((uint32_t)((int32_t)irqn)&(uint32_t)0x1F));
}
void TIM2_IRQHandler(void)
{
  if(GPIOC->ODR&(1<<9))GPIOC->BRR=1<<9;else GPIOC->BSRR=1<<9;
  TIM2->SR=0;
}

void TIM3_IRQHandler(void)
{
if(GPIOC->ODR&(1<<8))GPIOC->BRR=1<<8;else GPIOC->BSRR=1<<8;
  TIM3->SR=0;
}

void TIM4_IRQHandler(void)
{

  TIM4->SR=0;
}

void TIM5_IRQHandler(void)
{

  TIM5->SR=0;
}

void TIM1_BRK_TIM9_IRQHandler(void)
{

  TIM9->SR=0;
}
void RCC_Config(void)
{ 
  SCB->CPACR|=((3UL<<10*2)|(3UL<<11*2));
  RCC->APB1ENR|=RCC_APB1ENR_PWREN;
  PWR->CR|=PWR_CR_VOS;
  RCC->CR|=RCC_CR_HSEON;
  while(RCC->CR&RCC_CR_HSERDY);//ждать запуска HSE
  RCC->PLLCFGR=(7<<24)|RCC_PLLCFGR_PLLSRC_HSE|(336<<6)|8;
  RCC->CR|=RCC_CR_PLLON;
  while(!(RCC->CR & RCC_CR_PLLRDY));//ждать запуска PLL
  FLASH->ACR=FLASH_ACR_ICEN|FLASH_ACR_DCEN|FLASH_ACR_LATENCY_5WS;
  RCC->CFGR=(8<<16)|(4<<13)|(5<<10)|RCC_CFGR_SW_PLL;
  while(!(RCC->CFGR&RCC_CFGR_SWS));//ждать переключения на PLL
  SysTick->CTRL=3;
  SysTick->LOAD=21000;
}
все остальные прерывания работают нормально(тим 6,7,9), смена приоритетов ничего не даёт
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 79
Зарегистрирован: Вт июн 18, 2013 11:23:25

Сообщение osievskiy »

Хмм я не спец, но что у тебя в main() ? Там бесконечный цикл стоит ?
Реклама
Мучитель микросхем
Сообщения: 478
Зарегистрирован: Ср окт 15, 2008 09:33:03
Откуда: Воронеж

Сообщение Galizin »

Попробуйте использовать макросы из стандартного файла stm32f4xx.h (название нужно уточнить) для обозначения битов.

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

TIM2->CR1=0x00000085;
TIM2->CR1=(TIM_CR1_ARPE|TIM_CR1_OPM|TIM_CR1_CEN);
Попробуйте выключить однопульсный режим.
Открыл глаза
Сообщения: 71
Зарегистрирован: Чт окт 28, 2010 11:20:39

Сообщение bishop-strip »

Вот вам мой код, вроде работает как надо....

три функции...

1. Включает прервыания, параметр - период срабатывания...
Спойлерvoid EnableTimer(uint32_t time)
{
/* Включаем таймер 6 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
/* Настраиваем таймер так чтоб он тикал почаще */
TIM2->PSC = 0;
TIM2->ARR = time;
TIM2->DIER |= TIM_DIER_UIE; //разрешаем прерывание от таймера
TIM2->CR1 |= TIM_CR1_CEN; // Начать отсчёт!
NVIC_EnableIRQ(TIM2_IRQn); //Разрешение TIM6_DAC_IRQn прерывания
}
2. выключает прервыания
Спойлерvoid DisableTimer()
{
NVIC_DisableIRQ(TIM2_IRQn); //Разрешение TIM2_IRQn прерывания
}
3. Сам обработчик прерывания от таймера
Спойлерvoid TIM2_IRQHandler()
{
// Ваш код......


/* Очищаем бит обрабатываемого прерывания */
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
Пример использования:
Спойлерvoid main()
{
EnableTimer(1000000);
//Все, включили таймер, теперь он запущен, прервания обрабатываются
while(1)
{}
}
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Аватара пользователя
Сообщения: 140
Зарегистрирован: Вт авг 03, 2010 15:21:20
Откуда: Екатеринбург

Сообщение zvukovik »

спасибо всем, заработало :))
Реклама
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Сообщение ut1wpr »

zvukovik писал(а):спасибо всем, заработало :))
Практически на всех форумах принято после своего вопроса и после получения положительного результата давать объяснение, что в конечном итоге привело к этому положительному результату. Даже если были собственные ошибки, пусть даже самые глупые. Именно на таких ошибках и учатся другие, ценность форумов в этом. А то как-то слегка эгоистически получается. "У меня не работает" - "А вы попробуйте то-то-то и то..." - "Всем спасибо, заработало. У меня. А вы сами ходите по этим граблям". Так?
С уважением,
Виктор.
Реклама
Родился
Сообщения: 2
Зарегистрирован: Ср сен 21, 2022 14:19:32

Сообщение slawiks »

Добрый день. Возникла та же проблема. Таймеры 9,10,11 работают нормально. А 6, 7, 2-5 - переключают светодиод только в отладчике. Пробовал выводить их счетный регистр в UART - значение меняется. Предложенный выше код также не помог...Подскажите, что еще можно посмтотреть..
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="slawiks",url="/forum/viewtopic.php?p=4292680#p4292680"]Подскажите, что еще можно посмтотреть..[/uquote]А может для начала надо что-то показать? В хрустальном шаре вашу проблему не видно.

Пока лишь могу посоветовать переместить команду очистки флага прерывания в самое начало чтобы исклчить двойное срабатывание прерывания, что может визуально выглядет как "немигание" диода.
Родился
Сообщения: 2
Зарегистрирован: Ср сен 21, 2022 14:19:32

Сообщение slawiks »

Спасибо. Как раз это вчера и решило проблему, хотя до этого нигде не встречал рекомендаций вначале сбрасывать флаг. Действительно, когда ткнулся осциллографом, обнаружил очень короткие импульсы...
Встал на лапы
Аватара пользователя
Сообщения: 145
Зарегистрирован: Пн апр 02, 2012 15:56:23

Сообщение azhel12 »

А как так? Пока флаг не сброшен, повторно прерывание не сгенерируется, то есть вроде как логично выполнить все необходимые действия и только потом сбросить, что гарантирует выполнение всех операторов тела прерывания.
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

azhel12, ++
Флаг можно сбрасывать лишь в самом конце прерывания. Чтобы гарантировать, что не будет повторных входов, пока ты еще там.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="azhel12",url="/forum/viewtopic.php?p=4293176#p4293176"]А как так? Пока флаг не сброшен, повторно прерывание не сгенерируется, то есть вроде как логично выполнить все необходимые действия и только потом сбросить[/uquote]Если скорость работы ядра контроллера выше скорости работы шины, на которой висит устройство вызвавшее прерывание, то процедура "сброс флага" может длиться дольше выхода из прерывания и ядро "ловит" то же прерывание вторично. Это если на пальцах.

[uquote="azhel12",url="/forum/viewtopic.php?p=4293176#p4293176"]что гарантирует выполнение всех операторов тела прерывания.[/uquote]Прервать выполнение может только прерывание с более высоким приоритетом. Тут уже флаг текущего прерывания никак не влияет. Только полный запрет всех прерываний.

Добавлено after 1 minute 1 second:
[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4293181#p4293181"]Флаг можно сбрасывать лишь в самом конце прерывания. Чтобы гарантировать, что не будет повторных входов, пока ты еще там.[/uquote]Откуда возьмутся повторные входы "пока ты ещё там"? А вот повторные когда ты "уже не там" запросто.
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4293202#p4293202"]Откуда возьмутся повторные входы "пока ты ещё там"? А вот повторные когда ты "уже не там" запросто.[/uquote]
Да элементарно: сработало прерывание, тебя отфутболили в обработчик. Ты тут же снимаешь флаг, и внезапно, пока еще не вышел из обработчика, МК опять в него заходит (т.к. флаг-то сброшен). Я на такое когда-то наталкивался, когда у меня обработчик прерывания очень длинный был и выполнялся аж пару десятков микросекунд. Не всегда бывает возможность обработчик прерывания сделать коротким, просто выставляя флаги...
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4293229#p4293229"]Ты тут же снимаешь флаг, и внезапно, пока еще не вышел из обработчика, МК опять в него заходит (т.к. флаг-то сброшен).[/uquote]Чего? Прерывание с тем же приоритетом не может себя прервать.

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4293229#p4293229"]Я на такое когда-то наталкивался, когда у меня обработчик прерывания очень длинный был[/uquote]Условия возникновения прерываний возникали чаще, чем ты успевал их обрабатывать. Новый обработчик запускался сразу же после выхода из предыдущего, но никак не прерывал выполняющийся. Это невозможно.
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

Ну, если так, то вообще без разницы, когда снимается флаг прерывания.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Eddy_Em",url="/forum/viewtopic.php?p=4293250#p4293250"]Ну, если так, то вообще без разницы, когда снимается флаг прерывания.[/uquote]Это ты slawiks расскажи :)
Ответить

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