Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

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

Вт июл 09, 2013 11:04:43

пытаюсь запустить прерывания от таймеров 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), смена приоритетов ничего не даёт

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

Вт июл 09, 2013 12:16:44

Хмм я не спец, но что у тебя в main() ? Там бесконечный цикл стоит ?

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

Вт июл 09, 2013 14:42:26

Попробуйте использовать макросы из стандартного файла stm32f4xx.h (название нужно уточнить) для обозначения битов.
Код:
TIM2->CR1=0x00000085;
TIM2->CR1=(TIM_CR1_ARPE|TIM_CR1_OPM|TIM_CR1_CEN);

Попробуйте выключить однопульсный режим.

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

Вт июл 16, 2013 23:45:51

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

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

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)
{}
}

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

Пт авг 09, 2013 14:01:19

спасибо всем, заработало :))

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

Пт авг 09, 2013 16:00:18

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

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

Ср сен 21, 2022 14:23:34

Добрый день. Возникла та же проблема. Таймеры 9,10,11 работают нормально. А 6, 7, 2-5 - переключают светодиод только в отладчике. Пробовал выводить их счетный регистр в UART - значение меняется. Предложенный выше код также не помог...Подскажите, что еще можно посмтотреть..

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

Ср сен 21, 2022 21:47:06

Подскажите, что еще можно посмтотреть..
А может для начала надо что-то показать? В хрустальном шаре вашу проблему не видно.

Пока лишь могу посоветовать переместить команду очистки флага прерывания в самое начало чтобы исклчить двойное срабатывание прерывания, что может визуально выглядет как "немигание" диода.

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

Чт сен 22, 2022 08:18:43

Спасибо. Как раз это вчера и решило проблему, хотя до этого нигде не встречал рекомендаций вначале сбрасывать флаг. Действительно, когда ткнулся осциллографом, обнаружил очень короткие импульсы...

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

Чт сен 22, 2022 09:02:32

А как так? Пока флаг не сброшен, повторно прерывание не сгенерируется, то есть вроде как логично выполнить все необходимые действия и только потом сбросить, что гарантирует выполнение всех операторов тела прерывания.

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

Чт сен 22, 2022 09:19:10

azhel12, ++
Флаг можно сбрасывать лишь в самом конце прерывания. Чтобы гарантировать, что не будет повторных входов, пока ты еще там.

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

Чт сен 22, 2022 10:19:09

А как так? Пока флаг не сброшен, повторно прерывание не сгенерируется, то есть вроде как логично выполнить все необходимые действия и только потом сбросить
Если скорость работы ядра контроллера выше скорости работы шины, на которой висит устройство вызвавшее прерывание, то процедура "сброс флага" может длиться дольше выхода из прерывания и ядро "ловит" то же прерывание вторично. Это если на пальцах.

что гарантирует выполнение всех операторов тела прерывания.
Прервать выполнение может только прерывание с более высоким приоритетом. Тут уже флаг текущего прерывания никак не влияет. Только полный запрет всех прерываний.

Добавлено after 1 minute 1 second:
Флаг можно сбрасывать лишь в самом конце прерывания. Чтобы гарантировать, что не будет повторных входов, пока ты еще там.
Откуда возьмутся повторные входы "пока ты ещё там"? А вот повторные когда ты "уже не там" запросто.

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

Чт сен 22, 2022 11:01:05

Откуда возьмутся повторные входы "пока ты ещё там"? А вот повторные когда ты "уже не там" запросто.

Да элементарно: сработало прерывание, тебя отфутболили в обработчик. Ты тут же снимаешь флаг, и внезапно, пока еще не вышел из обработчика, МК опять в него заходит (т.к. флаг-то сброшен). Я на такое когда-то наталкивался, когда у меня обработчик прерывания очень длинный был и выполнялся аж пару десятков микросекунд. Не всегда бывает возможность обработчик прерывания сделать коротким, просто выставляя флаги...

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

Чт сен 22, 2022 11:18:06

Ты тут же снимаешь флаг, и внезапно, пока еще не вышел из обработчика, МК опять в него заходит (т.к. флаг-то сброшен).
Чего? Прерывание с тем же приоритетом не может себя прервать.

Я на такое когда-то наталкивался, когда у меня обработчик прерывания очень длинный был
Условия возникновения прерываний возникали чаще, чем ты успевал их обрабатывать. Новый обработчик запускался сразу же после выхода из предыдущего, но никак не прерывал выполняющийся. Это невозможно.

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

Чт сен 22, 2022 11:39:28

Ну, если так, то вообще без разницы, когда снимается флаг прерывания.

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

Чт сен 22, 2022 12:03:42

Ну, если так, то вообще без разницы, когда снимается флаг прерывания.
Это ты slawiks расскажи :)
Ответить