How to reset STM32 timer?

Viewed 60

I want to connect my MCU with a module which has a specific way of communication. Module sends messages of variable number of characters, where period between two characters is also variable. My idea is to use timer in order to overcome this problem. Let's assume that module sends 5 characters. After reception of the first character, timer will be activated. Assuming that the second character is sent shortly after the first, after it's reception timer will be reset and started again. Principe is the same for the rest 3 characters. As there is no more data to receive, timer will reach it's predefined, experimentally defined value and generate interrupt, therefore notify MCU about one full message reception.

In a nutshell, timer will be reset after reception of each character.

I want to configure TIM7 in normal mode on STM32G070. My main problem is how to reset timer. There are several ways I came across the internet:

  1. Enable/disable CEN bit in CR1 register - timer stops counting and keeps the current value (no reset, no interrupt). This method demands to set timer at initial value (I'm still not sure how), thus spending time
  2. Set UG bit in EGR register - timer is reloaded but global interrupt is triggered by setting UIF bit in SR register (interrupt should be activated only at the reception of the last character).

Reading MCU's reference manual doesn't gave me any idea how to reset timer. As mentioned above, is there a way to reset the timer?

2 Answers

Everything you need it to:

TIM7 -> ARR = 0;
TIM7 -> CR1 &= ~TIM_CR1_UDIS;
TIM7 -> EGR = TIM_EGR_UG;
TIM7 -> CR1 |= TIM_CR1_UDIS;

Configuring the timer peripheral only needs to be done once, in the initialization part of the code and before the infinite loop. In this part you set the time for each increment of the counter (1us, 0.1ms, etc.) and also the value the counter needs to reach for interrupt to be generated.

In this case, seems that you need to disable the timer after the interrupt event (full message received), and re-enable it (and also re-enable the interrupt) after receiving the first data again (start of the new message). Which is done by CEN bit of the CR1 register as you said and UIE bit of the CR2 register. This way, the timer will not generate unnecessary interrupts when there's no data transfer going on.

And to restart the timer you just need to write 0 to the counter register after receiving each byte. So:

// after receiving first byte
TIM7->CR1 |= 0x01; // set the CEN
TIM7->CR2 |= 0x01; // set the UIE bit for interrupt generation

// after receiving each byte
timerValue = TIM7->CNT; // save the time
TIM7->CNT &= 0x0; // restart the timer

// in the timer interrupt callback routine (after receiving last byte)
TIM7->CR2 &= ~(0x01); // disable the interrupt
TIM7->CR1 &= ~(0x01); // disable the counter, this won't be necessary
Related