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

 
 
> 32stmf0 timer interrupts, при инициализации СРАЗУ прерывает
alexf
сообщение Sep 28 2016, 02:20
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
ViKo
сообщение Sep 28 2016, 04:31
Сообщение #2


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

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



Попробуйте очистить SR до того, как разрешите работу.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 28 2016, 04:51
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Перед тем как разрешать прерывания надо чистить и регистр флагов таймера и соответствующий бит в регистре NVIC.CLRPEND.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 28 2016, 06:14
Сообщение #4


фанат дивана
******

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



Цитата(alexf @ Sep 28 2016, 07:20) *
Проект на STM32F070. Timer3 используется для задержки. Простейший режим: считаем вверх до ARR, прерывание по переполнению. Почему то после инициализации первое прерывание происходит СРАЗУ. Вне зависимости от прескалера и ARR. А дальше все как и положено.

Дело в том, что регистр PSC (как и ARR, если мне не изменяет память) буферизован, и обновляется только при переполнении таймера.
Чтобы изменить прескалер немедленно, надо сгенерировать событие переполнения:
Код
    TIM3->EGR = TIM_EGR_UG;


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
alexf
сообщение Sep 28 2016, 07:58
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 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.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 28 2016, 09:49
Сообщение #6


фанат дивана
******

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



Цитата(alexf @ Sep 28 2016, 12:58) *
Я так понял что ARR может быть буферизован или нет в зависимости от CR1->ARPE. Но проблема не в PSC.

Да, буферизация ARR отключается. (И вы ее отключили). А вот буферизация PSC - нет. Таким образом, вы думаете, что PSC равен PrescalerValue, а в действительности он у вас равен 0. Поэтому, когда вы задаёте ARR 2, то таймер срабатывает через 2 цикла.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
alexf
сообщение Sep 28 2016, 21:08
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 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. В общем мой костыль работает надежно, так и оставлю.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 28 2016, 22:10
Сообщение #8


фанат дивана
******

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



Цитата(alexf @ Sep 29 2016, 02:08) *
В общем мой костыль работает надежно, так и оставлю.

Так вот вместо этого вашего костыля (ждать, когда наступит переполнение), ST придумали специальный битик TIM_EGR_UG, который вызывает переполнение сразу, без ожидания.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Sep 29 2016, 10:55
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(AHTOXA @ Sep 29 2016, 00:10) *
Так вот вместо этого вашего костыля (ждать, когда наступит переполнение), ST придумали специальный битик TIM_EGR_UG, который вызывает переполнение сразу, без ожидания.

Так продолжи: проинициализировать ARR, PSC, взвести _UG, почистить флаги прерываний, разрешить оные, - и поехали...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Sep 29 2016, 11:27
Сообщение #10


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

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



Я так запускаю:
Код
  TIM7->PSC = нечто...;
  TIM7->ARR = нечто...;
  TIM7->EGR = TIM_EGR_UG;
  TIM7->SR = 0;        
  TIM7->CR1 |= TIM_CR1_CEN;

А. Прерывания не использовал. Просто ждал, когда в статусе появится флаг.
Go to the top of the page
 
+Quote Post
alexf
сообщение Sep 30 2016, 04:02
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 420
Регистрация: 22-12-04
Пользователь №: 1 608



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


Да, спасибо. Нашел уже этот битик.
Go to the top of the page
 
+Quote Post
x893
сообщение Sep 30 2016, 05:00
Сообщение #12


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

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Можно установить
DBGMCU_APB1_FZ_DBG_TIM3_STOP
и отладчиком пройтись - сразу видно будет
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 08:34
Рейтинг@Mail.ru


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