Skip to main content
Graduate
March 18, 2024
Question

Timer22 never reach IRQ

  • March 18, 2024
  • 5 replies
  • 1367 views

Hi everyone,

It seems that I have a problem with my Timer 22 configuration, on my Microcontroller, STM32L031 I would like to stop it then restart them with a lower speed to go into sleep mode, except that my interrupt is never triggered.

 

Do you have an idea ?

 

 

 

 

//-----------------------------------------------------------------------------
void SLEEP_LP(uint16_t time)
//-----------------------------------------------------------------------------
{
HAL_NVIC_DisableIRQ(TIM21_IRQn);	//---- Disable other timer IRQ for debug
HAL_NVIC_DisableIRQ(TIM2_IRQn);

RCC->APB2ENR &= ~RCC_APB2ENR_TIM22EN;	//--- Disable Clock to reconf tim 22
TIM22->CR1 &= ~TIM_CR1_CEN; 		//--- Disable count
TIM22->SR = 0x00;


//--- Re Configuration Timer22 ---
RCC->APB2ENR |= RCC_APB2ENR_TIM22EN; //--- Enable Clock Tim22
TIM22->PSC = 65; 	//--- Prescaler : clock timer = 65536Hz/(prescaler+1) => ~1kHz
TIM22->ARR = time; 	//--- Auto reload Register
TIM22->DIER |= TIM_DIER_UIE; 	//--- Enable interrupt

RCC->APB1ENR |= RCC_APB1ENR_PWREN;	
RCC->ICSCR &= (~RCC_ICSCR_MSIRANGE);	//--- MSI to 65,536kHz

//	volatile uint64_t ii = HAL_RCC_GetSysClockFreq();
TIM22->CR1 |= TIM_CR1_CEN; 	//--- Enable count
PWR->CR |= PWR_CR_LPSDSR; 	//--- voltage regulator in low-power mode during sleep
SCB->SCR &= ~( SCB_SCR_SLEEPDEEP_Msk ); //--- low-power mode = sleep mode
FLASH->ACR |= FLASH_ACR_SLEEP_PD;	//-- Flash OFF
while (end_sleep_flag == FALSE) __WFI();	//--- enter low-power mode
}



//-----------------------------------------------------------------------------
void TIM22_IRQHandler(void)
//-----------------------------------------------------------------------------
{
	TIM22->SR = 0; 				//--- Clear Flag
	end_sleep_flag = TRUE;
}

 

 

 

 

Thanks,

 

 

 

    This topic has been closed for replies.

    5 replies

    Super User
    March 18, 2024

    > RCC->APB2ENR &= ~RCC_APB2ENR_TIM22EN; //--- Disable Clock to reconf tim 22

    No. You cannot write to TIM registers, if TIM has no clock. It means, the timer is running when you do this, and CNT is nonzero.

    So, if you don't have ARR preload set, and you set it to value lower than CNT, it will count up until the "natural overflow" i.e. 65535. New prescaler won't get active until the next Update, so if prescaler was previously big enough, this may take too long time (minutes, hours).

    Also, note, that setting ARR to 0 stops the timer.

    JW

     

    Graduate
    March 18, 2024

    Yes, I have change my code according to your remarks, but 2 questions ?

    First Did i need to stop the timer count before reconfigure them ?

     

    Second : according to your remark i have added these line to have to take imediately my ARR value, is this correct ?

    	TIM22->CR1 |= TIM_CR1_CEN; 				//--- Enable count
    	TIM22->CNT = 0xFFFFFFFF - 1; // unint_32
    
    	while (end_sleep_flag == FALSE) __WFI();	//--- enter low-power mode

     

    Thanks for your help,

    Super User
    March 18, 2024

    The exact steps depend on exactly what do you want to achieve, but generally I'd recommend this sequence:

    //--- Re Configuration Timer22 --- timer is already running
    TIM22->CR1 &= ~TIM_CR1_CEN; 		//--- Disable count
    TIM22->DIER = 0; 	//--- Disable interrupt
    TIM22->PSC = 65; 	//--- Prescaler : clock timer = 65536Hz/(prescaler+1) => ~1kHz
    TIM22->ARR = time; 	//--- Auto reload Register
    TIM22->EGR = TIM_EGR_UG; // generate Update event to force loading of prescaler (and ARR if ARPE=1)
    TIM22->CNT = 0; // this is here to generate delay, see comment
    TIM22->SR = 0; // clear flags
    TIM22->DIER |= TIM_DIER_UIE; 	//--- Enable interrupt

    Writing 0 to CNT may not be needed, as that is cleared as side effect of setting TIM_EGR.UG, see description of that bit in RM. However, that step is there to insert a delay because it takes an few cycles until writes to TIMx_EGR take effect. This is not documented by ST, and as I wrote in that post, I am not sure about the timing, I am not ST insider; so test this and if you find the Update interrupt firing immediately after being enabled, this may be the area for changes.

    JW

     

     

    Graduate
    March 18, 2024

    I havent use this register before i have added it

    TIM_EGR_UG

    Unfortunately my interrupt is still not called, but I think it's a problem of definition, because i have try many configuration, like interrupt with copare mode but I don't know yet, because in my opinion I respect the name of the call back function.

    //-----------------------------------------------------------------------------
    void TIM22_IRQHandler()
    //-----------------------------------------------------------------------------
    {
    	TIM22->SR = 0; 				//--- Clear Flag
    	timer22.flagFinVeille = TRUE;
    	GPIO_VERTE_ON;
    }

    Quentin_27_0-1710772116315.png

    And above all the SR register generates an event, but the function is never called...

     

    Thanks 

    Super User
    March 18, 2024

    > SR register generates an event, but the function is never called

    So, you have read out TIM22 registers, SR has UIF set, DIER has UIE set, correct?

    And the interrupt does not fire, even if you don't enter sleep?

    Is this interrupt enabled in NVIC?

    Here is a generic checklist for "interrupt does not fire" cases.

    JW