cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with TIM1 operation in the PeriodElapsedCallback of TIM4

Raahul Jagannathan
Associate II
Posted on July 04, 2018 at 10:36

I am working on a 3 channel frequency counter on STM32F446RE. I am displaying the values on an LCD 20x4 display. The LCD driver uses TIM1 in order to generate the microsecond and millisecond delays. I am also using TIM4 in order to interrupt normal system operation every 1 second, and print the current values stored in the frequency variables. But inside the timer interrupt TIM1 is not working. It get stuck in the loop,

static void LCD1602_TIM_MicorSecDelay(uint32_t uSecDelay)

{

TIM1->ARR = uSecDelay-1;

TIM1->SR &= ~(0x0001); // Clear UEV flag

TIM1->CR1 |= 1UL;

while((TIM1->SR&0x0001) != 1); // (THIS IS THE LOOP IT GETS STUCK IN)

}

The timer configuration in the driver is:

static void LCD1602_TIM_Config(void)

{

RCC_ClkInitTypeDef myCLKtypeDef;

uint32_t clockSpeed;

uint32_t flashLatencyVar;

HAL_RCC_GetClockConfig(&myCLKtypeDef, &flashLatencyVar);

if(myCLKtypeDef.APB2CLKDivider == RCC_HCLK_DIV1)

{

clockSpeed = HAL_RCC_GetPCLK1Freq();

}

else

{

clockSpeed = HAL_RCC_GetPCLK1Freq()*2;

}

clockSpeed *= 0.000001;

//Enable clock for TIM2 timer

RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // 0x1

//Set the mode to Count up

TIM1->CR1 &= ~(0x0010);

//Enable Update Event

TIM1->CR1 &= ~(0x0001);

//Update request source

TIM1->CR1 &= ~(1UL << 2);

// Set bit 3 High to enable One-Pulse mode

TIM1->CR1 |= (1UL << 3);

//Set the Prescalar

TIM1->PSC = clockSpeed-1;

//Set and Auto-Reload Value to delay the timer 1 sec

TIM1->ARR = 10-1; // The Flag sets when overflows

//Event generation handling to reset the counter

TIM1->EGR = 1; //Update generate auto

TIM1->SR &= ~(0x0001); //Clear Update interrupt flag

}

static void LCD1602_TIM_MicorSecDelay(uint32_t uSecDelay)

{

TIM1->ARR = uSecDelay-1;

TIM1->SR &= ~(0x0001); // Clear UEV flag

TIM1->CR1 |= 1UL;

while((TIM1->SR&0x0001) != 1);

}

The Interrupt is shown below too:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

freq_disp();

}

With the interrupt being handled by an interrupt handler.

1 REPLY 1
Posted on July 04, 2018 at 14:13

Couple of observations, there are more efficient ways to do register level programming, the SR should be reset with a Write, not a RMW operation.

Instead of using the TIM like this, consider just configuring it in a maximal free running mode, where ARR=0xFFFF, it ticks at 1 MHz, and you observed the elapse of micro-seconds by doing a delta computation of CNT. This will be both interrupt and thread safe.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..