Question
Chain two timers
hi friends,
I try chain of 2 timers on STM32L053. From 2 16 bit timers I would like to create one 32bit timer.
My init is here.
void CLOCK__TIM21_Init(uint16_t Prescaler) {
//initialize tim21 as master
//enable clock to tim21
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM21);
//stop the timer to configure it
LL_TIM_DisableCounter(TIM21); //clear cen. 0=disable the timer, 1=enable the timer
LL_TIM_SetClockDivision(TIM21, LL_TIM_CLOCKDIVISION_DIV1); //clear CKD0..1. 0b00->1x clock; 0b01->2:1 clock, 0b10->4:1 clk; 0b11->reserved
LL_TIM_SetCounterMode(TIM21, LL_TIM_COUNTERMODE_UP); //clear DIR bit. 0=upcounter, 1=downcounter
LL_TIM_SetOnePulseMode(TIM21, LL_TIM_ONEPULSEMODE_REPETITIVE); //clear opm bit. 0=periodic timer, 1=one-shot timer
//or to simply zero the register
LL_TIM_SetTriggerOutput(TIM21, LL_TIM_TRGO_UPDATE); //MMS = 0b010->tim2 as prescaler
//source from internal clock -> disable slave mode
LL_TIM_SetSlaveMode(TIM21, LL_TIM_SLAVEMODE_DISABLED); //clear sms->master mode and use internal clock
//clear the status register bits for capture / compare flags
LL_TIM_ClearFlag_UPDATE(TIM21);
LL_TIM_ClearFlag_CC4(TIM21);
LL_TIM_ClearFlag_CC3(TIM21);
LL_TIM_ClearFlag_CC2(TIM21);
LL_TIM_ClearFlag_CC1(TIM21);
//disable the interrupt by clearing the enable bits
LL_TIM_DisableIT_CC1(TIM21);
LL_TIM_DisableIT_CC2(TIM21);
LL_TIM_DisableIT_CC3(TIM21);
LL_TIM_DisableIT_CC4(TIM21);
LL_TIM_DisableIT_UPDATE(TIM21);
//set the prescaler
LL_TIM_SetPrescaler(TIM21, Prescaler - 1); //set the prescaler to Prescaler
//user can specify a prescaler here. otherwise use 0xffff
LL_TIM_SetAutoReload(TIM21, 0xffff); //auto reload register / period = 0; - need to change for downcounters
LL_TIM_SetCounter(TIM21, 0); //reset the counter
//enable the timer.
// go
LL_TIM_EnableCounter(TIM21);
}
void CLOCK__TIM22_Init(void) {
//initialize tim22 as slave
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM22);
LL_TIM_DisableCounter(TIM22); //clear cen. 0=disable the timer, 1=enable the timer
LL_TIM_SetClockDivision(TIM22, LL_TIM_CLOCKDIVISION_DIV1); //clear CKD0..1. 0b00->1x clock; 0b01->2:1 clock, 0b10->4:1 clk; 0b11->reserved
LL_TIM_SetCounterMode(TIM22, LL_TIM_COUNTERMODE_UP); //clear DIR bit. 0=upcounter, 1=downcounter
LL_TIM_SetOnePulseMode(TIM22, LL_TIM_ONEPULSEMODE_REPETITIVE); //clear opm bit. 0=periodic timer, 1=one-shot timer
//source from internal clock -> disable slave mode
LL_TIM_SetSlaveMode(TIM22, LL_TIM_SLAVEMODE_DISABLED); //clear sms->master mode and use internal clock
//clear the status register bits for capture / compare flags
LL_TIM_ClearFlag_UPDATE(TIM22);
LL_TIM_ClearFlag_CC4(TIM22);
LL_TIM_ClearFlag_CC3(TIM22);
LL_TIM_ClearFlag_CC2(TIM22);
LL_TIM_ClearFlag_CC1(TIM22);
//disable the interrupt by clearing the enable bits
LL_TIM_DisableIT_CC1(TIM22);
LL_TIM_DisableIT_CC2(TIM22);
LL_TIM_DisableIT_CC3(TIM22);
LL_TIM_DisableIT_CC4(TIM22);
LL_TIM_DisableIT_UPDATE(TIM22);
//set the prescaler
LL_TIM_SetPrescaler(TIM22, 0); //set the prescaler to 1:1 - master timer acts as prescaler
LL_TIM_SetAutoReload(TIM22, 0xffff); //auto reload register / period = 0; - need to change for downcounters
LL_TIM_SetCounter(TIM22, 0); //reset the counter
//enable the timer.
LL_TIM_EnableCounter(TIM22); //enable the timer
//source from trgo -> enable slave mode and trigger on trgo
LL_TIM_SetTriggerInput(TIM22, LL_TIM_TS_ITR0);
LL_TIM_SetClockSource(TIM22, LL_TIM_CLOCKSOURCE_EXT_MODE1);
}And My init function is:
CLOCK__TIM21_Init(32000);
CLOCK__TIM22_Init();And I want to use it, for read uptime my board.
uint32_t Timer_time(void) {
uint16_t msw, lsw; //timer's high/low words
do {
msw = LL_TIM_GetCounter(TIM22);
lsw = LL_TIM_GetCounter(TIM21);
} while (msw != LL_TIM_GetCounter(TIM22)); //see if overflow has taken place
return (msw << 16) | lsw; //return 32-bit time
}
For uptime I call this function:
void SerialConsole_timeUP(void) {
print("Time : %u sec", (uint32_t )Timer_Time() / 1000u);
}And my problem is:
- Start time is set about: 1384 sec
- increment is only in range: cca 1384 to 1441
For settings I use this document: https://www.st.com/resource/en/application_note/dm00042534-stm32-crossseries-timer-overview-stmicroelectronics.pdf
Does anybody see any problems?