|
32stmf0 timer interrupts, при инициализации СРАЗУ прерывает |
|
|
|
Sep 28 2016, 02:20
|
Местный
  
Группа: Свой
Сообщений: 420
Регистрация: 22-12-04
Пользователь №: 1 608

|
Прошу прощения ели тема поднималась - не нашел. Проект на STM32F070. Timer3 используется для задержки. Простейший режим: считаем вверх до ARR, прерывание по переполнению. Почему то после инициализации первое прерывание происходит СРАЗУ. Вне зависимости от прескалера и ARR. А дальше все как и положено. После долгих упражнений решил обмануть - первый раз жду переполнения, благо ждать микросекунды, и сбрасываю. Так работает, но как то коряво. В чем собственно корень зла? Пробовал инизиализачию и через HAL и напрямую. Без разницы. Код void Timer3Init(void){
int PrescalerValue = (uint32_t)(SystemCoreClock / 100000) - 1; TIM3->CR1 = 0; // disable timer TIM3->PSC = PrescalerValue; TIM3->ARR = 2; TIM3->CR1 = TIM_CR1_CEN; // Enable timer while((TIM3->SR & 1) == 0); // <*************** танец с бубном тут TIM3->CR1 = 0; // disable timer NVIC_ClearPendingIRQ(TIM3_IRQn); NVIC_EnableIRQ(TIM3_IRQn); // Enable interrupt from TIM3 (NVIC level) }
void StartTimer3(int timeout){ Timer3Expired = 0; TIM3->CR1 = 0; // disable timer TIM3->ARR = timeout / 10; TIM3->CR1 = TIM_CR1_CEN; // Enable timer TIM3->SR = 0; // clear interrupt flag TIM3->DIER = TIM_DIER_UIE; // Enable update interrupt (timer level) } На разных форумах читал что похожая фигня на других линейках, но ответа нигде не нашел. Вдруг тут повезет?
Сообщение отредактировал IgorKossak - Sep 28 2016, 09:54
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Sep 28 2016, 06:14
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(alexf @ Sep 28 2016, 07:20)  Проект на STM32F070. Timer3 используется для задержки. Простейший режим: считаем вверх до ARR, прерывание по переполнению. Почему то после инициализации первое прерывание происходит СРАЗУ. Вне зависимости от прескалера и ARR. А дальше все как и положено. Дело в том, что регистр PSC (как и ARR, если мне не изменяет память) буферизован, и обновляется только при переполнении таймера. Чтобы изменить прескалер немедленно, надо сгенерировать событие переполнения: Код TIM3->EGR = TIM_EGR_UG;
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 28 2016, 07:58
|
Местный
  
Группа: Свой
Сообщений: 420
Регистрация: 22-12-04
Пользователь №: 1 608

|
Цитата(jcxz @ Sep 27 2016, 21:51)  Перед тем как разрешать прерывания надо чистить и регистр флагов таймера и соответствующий бит в регистре NVIC.CLRPEND. А "NVIC_ClearPendingIRQ(TIM3_IRQn);" не это делает? SR чистил, не помогло. Цитата Дело в том, что регистр PSC (как и ARR, если мне не изменяет память) буферизован, Я так понял что ARR может быть буферизован или нет в зависимости от CR1->ARPE. Но проблема не в PSC.
|
|
|
|
|
Sep 28 2016, 21:08
|
Местный
  
Группа: Свой
Сообщений: 420
Регистрация: 22-12-04
Пользователь №: 1 608

|
Цитата(AHTOXA @ Sep 28 2016, 02:49)  Да, буферизация ARR отключается. (И вы ее отключили). А вот буферизация PSC - нет. Таким образом, вы думаете, что PSC равен PrescalerValue, а в действительности он у вас равен 0. Поэтому, когда вы задаёте ARR 2, то таймер срабатывает через 2 цикла. Задаю ARR=2 я специально, когда ХОЧУ чтобы первое переполнение было быстрее. А пока этого не делал, в ARR записывал 1500, но все равно СРАЗУ происходило первое переполнение. Возможно это делается специально чтобы записались ARR и PSC. В общем мой костыль работает надежно, так и оставлю.
|
|
|
|
|
Sep 29 2016, 10:55
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(AHTOXA @ Sep 29 2016, 00:10)  Так вот вместо этого вашего костыля (ждать, когда наступит переполнение), ST придумали специальный битик TIM_EGR_UG, который вызывает переполнение сразу, без ожидания. Так продолжи: проинициализировать ARR, PSC, взвести _UG, почистить флаги прерываний, разрешить оные, - и поехали...
|
|
|
|
|
Sep 30 2016, 04:02
|
Местный
  
Группа: Свой
Сообщений: 420
Регистрация: 22-12-04
Пользователь №: 1 608

|
Цитата(AHTOXA @ Sep 28 2016, 15:10)  Так вот вместо этого вашего костыля (ждать, когда наступит переполнение), ST придумали специальный битик TIM_EGR_UG, который вызывает переполнение сразу, без ожидания. Да, спасибо. Нашел уже этот битик.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|