|
|
  |
прерывание по таймеру, stm32f4xx |
|
|
|
Jan 24 2012, 15:25
|
Группа: Участник
Сообщений: 14
Регистрация: 24-01-12
Пользователь №: 69 851

|
Пробую сделать обычный таймер, вроде работает, но вот первое прерывание вызывается сразу же после старта. Т.е. настраиваю таймер на 5 секунд, делаю TIM_Cmd(TIM7, ENABLE), запускаю, микропроцессор стартует и сразу же срабатывает прерывание, затем все как надо, каждые пять секунд или сколько задам. Как сделать, чтобы не было первого "ложного" срабатывания? Запустил проц и только через N сек сработало. Вот код: CODE TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd ( RCC_APB1Periph_TIM7, ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Period = ms * 2; TIM_TimeBaseStructure.TIM_Prescaler = ( uint16_t ) ( SystemCoreClock / APB1_PRESCALER * 2 / 2000 ) - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit ( TIM7, &TIM_TimeBaseStructure );
TIM_ITConfig ( TIM7, TIM_IT_Update, ENABLE ); TIM_Cmd ( TIM7, ENABLE );
и обработчик прерывания: CODE void TIM7_IRQHandler ( void ) { if ( TIM_GetITStatus ( TIM7, TIM_IT_Update ) != RESET ) { TIM_ClearITPendingBit ( TIM7, TIM_IT_Update ); }
... }
Микропроцессор stm32f417
Сообщение отредактировал xheli - Jan 24 2012, 15:26
--------------------
|
|
|
|
|
Jan 24 2012, 16:27
|
Группа: Участник
Сообщений: 14
Регистрация: 24-01-12
Пользователь №: 69 851

|
Цитата(klen @ Jan 24 2012, 19:36)  первая мысль без обдумывания - а не занести ли в счетный регистр значение 1 перед пуском? Т.е. такое поведение нормально? TIM7->CNT = 1 не помогает, да и не правильно это. Вот так работает: Код TIM_ClearITPendingBit ( TIM7, TIM_IT_Update ); TIM_ITConfig ( TIM7, TIM_IT_Update, ENABLE ); TIM_Cmd ( TIM7, ENABLE );
Сообщение отредактировал IgorKossak - Jan 24 2012, 18:11
Причина редактирования: [code]
--------------------
|
|
|
|
|
Jan 25 2012, 07:55
|
Группа: Участник
Сообщений: 14
Регистрация: 24-01-12
Пользователь №: 69 851

|
Цитата(Aaron @ Jan 25 2012, 11:32)  я всегда и везде перед инициализацией прерываний очищаю сопутствующие флаги, и в аппнотах по-моему на все или почти все МК пишут так делать. спасибо, буду внимательнее
--------------------
|
|
|
|
|
Feb 20 2012, 14:56
|
Частый гость
 
Группа: Участник
Сообщений: 89
Регистрация: 3-01-11
Пользователь №: 61 997

|
Вопрос по таймерам в stm32. Не могу понять, почему преывание срабатывает через половину заданного интервала, то есть в 2 раза быстрее. Прерывания от таймера настроено на 1 сек, а срабатывает чрез 30 секунд. Настройки: Код: Код void SpeedSensorNVICTmrInit (void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(SSTIMER,TIM_IT_Update,ENABLE); } void TIM5_IRQHandler (void) // если сработало прерывание на 1 sec {
if (TIM_GetITStatus(TIM5,TIM_IT_Update)) { TIM_ClearITPendingBit(TIM5,TIM_IT_Update); // TmrOff(); //do smth; TmrOn(); } } void InitSpeedSensorTmr (TIM_TypeDef* TIM,unsigned short delay) { TIM_TimeBaseInitTypeDef Tim_InitStruct; Tim_InitStruct.TIM_ClockDivision=TIM_CKD_DIV1; Tim_InitStruct.TIM_CounterMode=TIM_CounterMode_Up; Tim_InitStruct.TIM_Period=delay; // Tim_InitStruct.TIM_Prescaler=35999; //36MHz/(35999+1)=1000 TIM_TimeBaseInit(TIM,&Tim_InitStruct);
TmrOn(); } Где TIM=TIM5, delay=1000. Используемый камень -stm32f107vet
|
|
|
|
|
Feb 22 2012, 05:31
|

Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 25-02-09
Из: Россия
Пользователь №: 45 369

|
Цитата Вопрос по таймерам в stm32. Не могу понять, почему преывание срабатывает через половину заданного интервала, то есть в 2 раза быстрее. Прерывания от таймера настроено на 1 сек, а срабатывает чрез 30 секунд. У меня была подобная проблема на STM32F2 Код void TIM7_IRQHandler(void) { if (TIM7->SR& TIM_SR_UIF) { ... //Почему-то не всегда сбрасывается, примерно через рас, иногда не регулярно. TIM7->SR = ~(uint16_t)TIM_SR_UIF; //if (TIM7->SR& TIM_SR_UIF)//Проверка. В системе только таймер, больше не чего. // while(1);//ОСТОРОЖНО Ж
//решил этим while (TIM7->SR& TIM_SR_UIF) TIM7->SR = ~(uint16_t)TIM_SR_UIF; }
}
|
|
|
|
|
Feb 23 2012, 08:37
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 11-02-09
Пользователь №: 44 714

|
Цитата(Sanya_kv @ Feb 22 2012, 08:31)  У меня была подобная проблема на STM32F2 Код void TIM7_IRQHandler(void) { if (TIM7->SR& TIM_SR_UIF) { ... //Почему-то не всегда сбрасывается, примерно через рас, иногда не регулярно. TIM7->SR = ~(uint16_t)TIM_SR_UIF; //if (TIM7->SR& TIM_SR_UIF)//Проверка. В системе только таймер, больше не чего. // while(1);//ОСТОРОЖНО Ж
//решил этим while (TIM7->SR& TIM_SR_UIF) TIM7->SR = ~(uint16_t)TIM_SR_UIF; }
} правильнее будет TIM7->SR &=~TIM_SR_UIF;
Сообщение отредактировал Vichkins - Feb 23 2012, 08:38
|
|
|
|
|
Feb 23 2012, 10:03
|

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

|
Цитата(Vichkins @ Feb 23 2012, 11:37)  правильнее будет TIM7->SR &=~TIM_SR_UIF; Если посмотрите на состав регистра SR в базовых таймерах, то увидите, что достаточно будет TIM7->SR = 0; Аналогично, для проверки достаточно while (!TIM7->SR)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|