2018-05-11 04:05 AM
I'm using STM32F030R8 @ 40MHz and TIM6. I want to wait for some time without blocking main function, so i used TIM6 - code below:
TIM6->CR1 |= TIM_CR1_ARPE | TIM_CR1_OPM;//auto-reload, one-pulse
TIM6->PSC = 4000-1;//100usec TIM6->ARR = 5000-1; //500ms for test TIM6->DIER |= TIM_DIER_UIE; //enable update interrupt NVIC_EnableIRQ(TIM6_IRQn);EXTI interrupt turns on the timer (TIM6->CR1 |= TIM_CR1_CEN). But after the first EXTI interrupt, first timer update interrupt is executing after 130us instead of 500ms. After the first interrupt everything works properly - I get 500ms delay.
EXTI interrupt code:
void EXTI4_15_IRQHandler(void)
{ if(EXTI->PR & EXTI_PR_PR13) { TIM6->CR1 |= TIM_CR1_CEN; GPIOA->BSRR = GPIO_BSRR_BS_5; EXTI->PR |= EXTI_PR_PR13; }}TIM6 interrupt code:
void TIM6_IRQHandler(void)
{ GPIOA->BSRR = GPIO_BSRR_BR_5; TIM6->SR &= ~(TIM_SR_UIF);}Do you know what I'm doing wrong?
2018-05-11 04:23 AM
Well UPDATE is defines as CNT == 0, so yes will fire immediately.
Don't do this
TIM6->SR &= ~(TIM_SR_UIF);
The hardware is designed to clear like this without the hazard your RMW version induces.
TIM6->SR = ~(TIM_SR_UIF);
2018-05-11 05:42 AM
'
I get 500ms delay.'
if can be done so much more easily with a free-running timer, without any of the complexity involved here.
2018-05-11 08:44 AM
TIMx_PSC is preloaded, i.e. the value you write does not get 'active' until the next update event. You can force an update by writing 1 to TIMx_EGR.UG, but then you'll to clear the update flag in SR to avoid immediate interrupt to fire.
I've participated in a related thread recently (there's a timing gotcha) and this comes up here regularly, try to search here.
JW
2018-05-11 04:49 PM
2018-05-13 03:02 AM
Thanks for advices. So, working code looks like that:
TIM6->ARR = 5000-1;
TIM6->CR1 |= TIM_CR1_CEN; //enable timer to generate update TIM6->EGR = TIM_EGR_UG; //software generated update - to set ARR TIM6->CR1 |= TIM_CR1_ARPE | TIM_CR1_OPM;//auto-reload, one-pulse TIM6->DIER |= TIM_DIER_UIE; //enable update interrupt TIM6->PSC = 4000-1; TIM6->SR = ~(TIM_SR_UIF); NVIC_EnableIRQ(TIM6_IRQn);There are few instructions between setting EGR and celaring SR flag, so everything works fine.
henry.****
- timerhave to be fired by EXTI interrupt. Free-running timer is useless in my case.