Chaining two 32-bit timers to obtain 64-bit timer resolution
Posted: Fri May 21, 2021 4:58 am
Hello,
STM Application Note AN2592 shows how one can chain two 16-bit timers in various STM32 MCUs to obtain a 32-bit timer:
https://www.st.com/resource/en/applicat ... ronics.pdf
Also, dannyf here in this forum has posted code on GitHub for the same purpose: https://github.com/dannyf00/STM32-Chaining-16bit-timers
And Rapita Systems (I have no link to them) has a blog post discussing exactly the same matter: https://www.rapitasystems.com/blog/chai ... er-stm32f4
Below is some code (which I have yet to test) that implements chaining two 32-bit timers to obtain what is effectively a timer with 64-bit resolution. Note that some, but not all STM32 MCUs have two 32-bit general purpose timers which can be chained. In the specific case of the STM32F411CEU6 MCU, these are TIM2 and TIM5.
One must take some precautions when reading the two 32-bit counter registers to put together a 64-bit counter value. I'll post later the code to do so, when I have tested it thoroughly.
STM Application Note AN2592 shows how one can chain two 16-bit timers in various STM32 MCUs to obtain a 32-bit timer:
https://www.st.com/resource/en/applicat ... ronics.pdf
Also, dannyf here in this forum has posted code on GitHub for the same purpose: https://github.com/dannyf00/STM32-Chaining-16bit-timers
And Rapita Systems (I have no link to them) has a blog post discussing exactly the same matter: https://www.rapitasystems.com/blog/chai ... er-stm32f4
Below is some code (which I have yet to test) that implements chaining two 32-bit timers to obtain what is effectively a timer with 64-bit resolution. Note that some, but not all STM32 MCUs have two 32-bit general purpose timers which can be chained. In the specific case of the STM32F411CEU6 MCU, these are TIM2 and TIM5.
Code: Select all
/* Chaining two 32-bit timers to obtain 64-bit timer resolution in the STM32F411CEU6
from an example of chaining two 16-bit timers, here:
https://www.rapitasystems.com/blog/chaining-two-16-bit-timers-together-stm32f4
We want TIM2 as the master (counts least significant 32 bits), TIM5 as the slave (counts most significant 32 bits). The result is a 64-bit timer.
*/
// Setup code:
// enable the clocks for the two timer peripherals:
RCC->APB1ENR |= RCC_APB1Periph_TIM2; // both timers are on APB1
RCC->APB1ENR |= RCC_APB1Periph_TIM5;
// Master - TIM2 counts the lower 32 bits
// TIM2 should be setup to use the clock settings that fit your application
TIM2->PSC = 0x00000000; // no prescaler
/* set clock division to zero: */
TIM2->CR1 &= (uint16_t)(~TIM_CR1_CKD);
TIM2->CR1 |= TIM_CKD_DIV1;
// Set TIM2 in Master Mode
TIM2->CR2 |= 0x20; // MMS (6:4) = 010
/* Slave - TIM5 counts the upper 16 bits */
TIM5->PSC = 0x00000000; // no prescaler
/* set clock division to zero: */
TIM5->CR1 &= (uint16_t)(~TIM_CR1_CKD);
TIM5->CR1 |= TIM_CKD_DIV1;
// Set TIM5 in Slave Mode
TIM5->SMCR |= (TIM_TS_ITR0 | TIM_SlaveMode_External1);
/* enable the two counters: */
TIM5->CR1 |= TIM_CR1_CEN;
TIM2->CR1 |= TIM_CR1_CEN;