alexf 0 28 сентября, 2016 Опубликовано 28 сентября, 2016 (изменено) · Жалоба Прошу прощения ели тема поднималась - не нашел. Проект на 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) } На разных форумах читал что похожая фигня на других линейках, но ответа нигде не нашел. Вдруг тут повезет? Изменено 28 сентября, 2016 пользователем IgorKossak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Попробуйте очистить SR до того, как разрешите работу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Перед тем как разрешать прерывания надо чистить и регистр флагов таймера и соответствующий бит в регистре NVIC.CLRPEND. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Проект на STM32F070. Timer3 используется для задержки. Простейший режим: считаем вверх до ARR, прерывание по переполнению. Почему то после инициализации первое прерывание происходит СРАЗУ. Вне зависимости от прескалера и ARR. А дальше все как и положено. Дело в том, что регистр PSC (как и ARR, если мне не изменяет память) буферизован, и обновляется только при переполнении таймера. Чтобы изменить прескалер немедленно, надо сгенерировать событие переполнения: TIM3->EGR = TIM_EGR_UG; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexf 0 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Перед тем как разрешать прерывания надо чистить и регистр флагов таймера и соответствующий бит в регистре NVIC.CLRPEND. А "NVIC_ClearPendingIRQ(TIM3_IRQn);" не это делает? SR чистил, не помогло. Дело в том, что регистр PSC (как и ARR, если мне не изменяет память) буферизован, Я так понял что ARR может быть буферизован или нет в зависимости от CR1->ARPE. Но проблема не в PSC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Я так понял что ARR может быть буферизован или нет в зависимости от CR1->ARPE. Но проблема не в PSC. Да, буферизация ARR отключается. (И вы ее отключили). А вот буферизация PSC - нет. Таким образом, вы думаете, что PSC равен PrescalerValue, а в действительности он у вас равен 0. Поэтому, когда вы задаёте ARR 2, то таймер срабатывает через 2 цикла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexf 0 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба Да, буферизация ARR отключается. (И вы ее отключили). А вот буферизация PSC - нет. Таким образом, вы думаете, что PSC равен PrescalerValue, а в действительности он у вас равен 0. Поэтому, когда вы задаёте ARR 2, то таймер срабатывает через 2 цикла. Задаю ARR=2 я специально, когда ХОЧУ чтобы первое переполнение было быстрее. А пока этого не делал, в ARR записывал 1500, но все равно СРАЗУ происходило первое переполнение. Возможно это делается специально чтобы записались ARR и PSC. В общем мой костыль работает надежно, так и оставлю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 28 сентября, 2016 Опубликовано 28 сентября, 2016 · Жалоба В общем мой костыль работает надежно, так и оставлю. Так вот вместо этого вашего костыля (ждать, когда наступит переполнение), ST придумали специальный битик TIM_EGR_UG, который вызывает переполнение сразу, без ожидания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 29 сентября, 2016 Опубликовано 29 сентября, 2016 · Жалоба Так вот вместо этого вашего костыля (ждать, когда наступит переполнение), ST придумали специальный битик TIM_EGR_UG, который вызывает переполнение сразу, без ожидания. Так продолжи: проинициализировать ARR, PSC, взвести _UG, почистить флаги прерываний, разрешить оные, - и поехали... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 29 сентября, 2016 Опубликовано 29 сентября, 2016 · Жалоба Я так запускаю: TIM7->PSC = нечто...; TIM7->ARR = нечто...; TIM7->EGR = TIM_EGR_UG; TIM7->SR = 0; TIM7->CR1 |= TIM_CR1_CEN; А. Прерывания не использовал. Просто ждал, когда в статусе появится флаг. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexf 0 30 сентября, 2016 Опубликовано 30 сентября, 2016 · Жалоба Так вот вместо этого вашего костыля (ждать, когда наступит переполнение), ST придумали специальный битик TIM_EGR_UG, который вызывает переполнение сразу, без ожидания. Да, спасибо. Нашел уже этот битик. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 55 30 сентября, 2016 Опубликовано 30 сентября, 2016 · Жалоба Можно установить DBGMCU_APB1_FZ_DBG_TIM3_STOP и отладчиком пройтись - сразу видно будет Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться