cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 Timer Encoder mode interrupt callback PeriodElapsed not firing

SRay.1
Associate III

STM32F103 MCU , CubeMX generated code for Atollic True studio.

TIM1 configured in Combine Channel -> Encoder Mode , User Parameter ->EncoderMode -> Ti1 and Ti2 , NVIC Settings -> TIM1 Update Interrupt enabled.

HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) - method implemented in main.c

contains only a GPIO LED toggle

main() method contain timer init generated code and timer start call

HAL_TIM_Encoder_Start_IT(&htim1,TIM_CHANNEL_ALL);

Also contains methods to print encoder counts.

As the encoder is turned, encoder counts are printed, but when the Counter period ARR - value over flows the interrupt is not fired.

Is period elapsed the correct call back? do i need to do something more?

I tried with TIM4 similar setting enabled global interrupt, but same results, encoder count is printed but overflow / underflow interrupt is no called.

Any suggestions?

Regards

Samit

1 ACCEPTED SOLUTION

Accepted Solutions
SRay.1
Associate III

After tring to wrap my head around a couple of hundred pages from RM0008 (Reference Manual STM32F1xx) and Datasheet and digging into the HAL code and HAL CHM files in Cube packages. It seems that the update event is configured by HAL_TIM_Base_Start_IT and the HAL_TIM_Encoder_Start_IT configures only the CC interrupts which is related to change of count......

So if you want update IT in encoder mode you got to start TIM_Base with IT.

View solution in original post

12 REPLIES 12

Does the interrupt routine itself (i.e. TIM1_UP_IRQHandler() ) get called?

If not, is the interrupt enabled in NVIC and TIMx_DIER; and is its name properly inserted in the interrupt vector (check in disasm)?

JW

SRay.1
Associate III

Will check this right away, in the mean while I have been busy trying all sorts of other option.

  1. I updated CubeMx from 5.3 to 5.6 and migrated the project nothing happened.
  2. I enabled all Interupts on TIM1 and implemented all interrupt call backs handler (period elapsed, OC_Delay, IC_Capture, PWM_PulseF...., Trigger, Error and corresponding Half methods too) only IC_Capture fired for each change in count
  3. I chained TIM4 using trigger from TIM1 on UPDATE and the trigger fires, i can see count increase on TIM4 as there is over/under flow in TIM1 encoder ARR
SRay.1
Associate III

Added a GPIO toggle into TIM1_UP_IRQHandler() and it does not get called.... about the TIMx_DIER and diasm... i will need a little bit more time....

The interrupt is enabled in NVIC (CubeMX) and Call HAL handler is also enabled (attached screen shot)

I have also checked that is TIM1 is setup as Base Timer the update handler works

In the chained setup of update trigger from TIM1 to TIM4 and TIM4 global interrupts enabled, I am getting trigger so TIM4->CNT increases on over/Under flow of TIM1

So i thought i could get Periad Elapsed for TIM4, so TIM4 ARR was set to 0, to get TIM4 Update on each trigger....Surprisingly update does not trigger So I set TIM4 ARR to 1 and TIM4 update gets triggered... however in the handler the instance checking does not work i get only "P_E" in the output....

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	CDC_Transmit_FS((uint8_t *)"P_E\n", 4);
 
	if(htim->Instance == TIM4) // THIS DOES NOT SEEM TO WORK
	{
		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
		CDC_Transmit_FS((uint8_t *)"Period Elapsed 4\n", 17);
	}
	else if( htim->Instance == TIM1) // NEITHER DOES THIS
	{
		CDC_Transmit_FS((uint8_t *)"Period Elapsed 1\n", 17);
	}
}

SRay.1
Associate III

screen shots here... forgot to attach

SRay.1
Associate III

forum allows to attach only one file ???

SRay.1
Associate III

Seems that

#define __HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__)    ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__))

is present in ./Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h and it is invoked via

  HAL_TIM_Base_Start_IT(&htim4);
  HAL_TIM_Encoder_Start_IT(&htim1,TIM_CHANNEL_ALL);

from my main.c

However there is no invocation of TIM1_UP_IRQHandler()....... and TIM4UP_IRQHandler() is invoked only if TIM4 ARR > 0.....but in call back htim->Instance does not work...

my brain hurts.....i think i am doing something stupid.... let me clean up everything and start over again....

TDK
Guru

Setting ARR=0 will not generate update events.

You can't just call CDC_Transmit_FS whenever you want and expect it to work. It's not putting data into a buffer. Check the return value. If the USB is busy, your call will do nothing.

FWIW, I had this exact thing working with a STM32F4 chip. I don't immediately see what you're doing wrong apart from the above two points, but that's a lot of code to look at.

If you feel a post has answered your question, please click "Accept as Solution".
SRay.1
Associate III

@TDK​  Yup... while reading the DS I figured that setting ARR=0 does not fire update. I was assuming that ARR=0 would fire update on every change.....

The CDC call to transmit sends data in the the VCP ( I am able to see the "hard coded" stuff in the CDC_Transmit) However I removed the USB stuff and everything else

Made a clean project and setup TIM1 as base timer with 35999 prescalar and ARR=1000 and Toggle pin on update interrupt.

This program has one line in main HAL_TIM_Base_Start_IT(&htim1); and function HAL_TIM_PeriodElapsedCallback() with HAL Toggle PIn

This clean project shows LED toggling at 1 HZ - which shows that update callback periosElapsed is working

After this I changed TIM1 to encoder mode 0 prescalar ARR=1000 Both TI1 & TI2, update interrupt enabled. Main.c contains one line HAL_TIM_Encoder_Start_IT(&htim1, TIM_CHANNEL_ALL) and the previous PerviousElapsed call back with a pin toggle nothing else.

Connected encoder to PA8 PA9 (working encoder) and give the shaft a few turns either way. encodet is 3400PPR X 4... i should be over / under flow in 1/4 turn causing pin to toggle.... but the pin does not toggle.....

This means that in encoder mode there is NO over/under flow in STM32F103. However i am able to chain TIM4 with TIM1 and get a trigger on update into TIM4 and TIM4 count did change..... which leads me to believe that the interrupt is not working. CubeMX 5.6 , TrueStudio 9.3.0 STMCube package 1.8

SRay.1
Associate III

@Community member​  Based on your suggestion i add toggle in the TIM1_UP_IRQHandler(), If the timer is started in Encoder mode Encoder_Start_IT then this IRQ does not get called. even if the update irq is enabled. However if the timer is started in base mode with interrupt, the IRQ handler is invokeda nd pin toggles...

I checked the .elf file in disassembly and the output is a bit overwhelming for my knowledge level.... However i was able to spot certain sections that appear to be related to setting the interrupt

08000268 <HAL_NVIC_EnableIRQ>: this section had a lot of machine instruction none of which made sense to me...

If you could walk me through on how to spot the naming i could give it a shot