cancel
Showing results for 
Search instead for 
Did you mean: 

Choosing a timer and what mode for only counting time periods.

Posted on April 19, 2017 at 12:06

I'm using HAL_TIM library for my timer proposal. I would like to count 100 us. My idea is starting to run a MCU timer in free run mode and having and interruption every this timer period. I have read there are several timers in my st used (stm32L476), and every timer has 3 or 4 channels: pwm, output mode, input capture, compare, etc.. But I don't know which will be the best for my proposal. I guess I can discard PWM modes or input capture mode, cause I only want to be internally counting time being passed, I don't want to be outputing any signal or reading an input pin. 

Which is the channel or mode I must choose in order to have an interruption every 100us, 10us, or Xus? (of course I know I must handle the interruptions by sw but first I need to count period in the correct channel/mode)

  • input capture
  • output compare
  • pwm generation
  • one pulse mode output.

Any help will be appreciate. Thanks in advance.

#timer-channels #hal #stm32l4-timer #hal_tim
35 REPLIES 35
Posted on April 20, 2017 at 10:10

Thank you for your detailed explanation. It's very helpful. 

Posted on April 28, 2017 at 12:49

Hi Clive and

Marsh.Nick

‌ I have another question related with time base. I have read that HAL libs works with systick time base (1ms by default). After this you can choose another time base source for HAL. Does it means that if I use a basic timer as T6 or T7 in time base mode for only have period counts, this will be the HAL new base time, replacing the old systick timebase source?

I have noticed that my app doesn't work if I don't write:

void SysTick_Handler(void)

{

HAL_IncTick();

}

at user code.

And there is only a unique ISR for time base interruption when tim irq is handled:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *TIMER_Struct)

{

flagElapsedTimPeriod=1; //my isr action

}

so I understand that the only systick interruption attended was the timer7.

Is it so? or am I wrong?

All correction will be helpful and welcome.

Best regards.

Posted on April 28, 2017 at 13:34

Not a specialist, however there might be a compile option somewhere to avoir HAL to use Systick (then maybe some functions needs to do the plumbing with a timer as substitute), as probably some RTOS may use Systick 1msec already?

One way to analyse the code would be to 'find in files' with SysTick as parameter. Understanding the mechanics will ensure that nothing is missing in it to operate properly.

Posted on April 28, 2017 at 15:05

The HAL is a mess I'm not digging into, you will need to own the static analysis task to get comfortable with how it works and interacts with itself. Find-in-Files can work, as can right-click context like 'Show Definition', etc. Tools like 'Understand' can be invaluable to do source code review. 

https://scitools.com/

 

The HAL_Delay() function uses the software incremented counter provided by SysTick or another timer calling HAL_IncTick. Something has to call it. A far safer method would be for HAL_Delay() to use the TIMx->CNT value of a hardware TIM ticking at 1us or 1ms across a 32-bit time line, not one repeatedly interrupting on a more frequent basis.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 28, 2017 at 16:28

Hi Eugenia and everyone,

When you make a source code for the microcontrollers, there are functions that need a time parameter for its proper operation, for example for communication peripherals as UART or SPI, you have to select a timeout value for a Tx/Rx transactions when you work on polling mode, those time values are controlled by the all the functions related to SysTick. By default, in the CubeMX the SysTick is generated by a dedicated SysTick Timer that configured correctly give the 1ms base time.

If you want to use another source for the SysTick you can choose any other Timer for this, when you choose the timer it won't be able for any other function (as free counting, pwm, etc), this could be set on CubeMX as you can see in the attached image.

0690X00000606tVQAQ.png

 If you want to use the SysTick as time base for make any action, you can use the HAL SysTick functions, one example of how to use those is the HAL_Delay() function:

0690X00000606lxQAA.png

When you catch the present value of the HAL_Tick, and then you keep comparing until the present value minus the start value be less of the delay time configured.

I suggest to use a dedicated base time for your own application, as the Time6 operating in free counting. About your question that why there 

is only a unique ISR for time base interruption for TIM6 a TIM7 thats is because those timers don't have any others interrupt sources as the TIM1 to TIM5. If you prove to use other timer there will be the callback functions for OutputCompare, InputCapture, PWM and of course the Period Ellapsed.

This IRQ code is for the TIM3:

0690X00000606tfQAA.png

Sorry for my english, hope to be useful!

Posted on April 28, 2017 at 16:53

>>

Sorry for my english

No problem with it here, looks good

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
roseanne qiu
Associate II
Posted on June 21, 2018 at 22:42

Dear Sir/Madam:

I just found that I have similar problems.  there are limit timers . timer 1, timer9 and timer10 are different from other timers. I have used timer2, timer3, timer4, and timer5 and their interrupts . to each timer, I use internal clock ,

once timers expire, they will create interrupt. My questions are

1. each timer , I only use one channel, there are more channels available, but I want their periods are different,

in my understanding, if you use multiple channels from one timer, their period have to be the same?

if not same, how could I do that? and how could I enable or disable each channel to separate them?

2. if above 1 does not work for multiple channels from one timer, I try to use different timer for each event,

but I found that I could not make  timer1, timer9 and timer10 work for their interrupt

I could only make timer2, timer3, timer4 and timer5 interrupts work.

1. here are my configures for working timers' interrupt:

/*########## Configure TIMx x = 2,3,4,5 ######################################*/

void TIMx_IRQHandler()

{

HAL_TIM_IRQHandler(&TimxHandle);

}

// Timer is configured to rollover every 1 secs 

__TIMx_CLK_ENABLE();

TimxHandle.Init.Prescaler = 16400;

TimxHandle.Init.CounterMode = TIM_COUNTERMODE_UP;

TimxHandle.Init.Period = 5000;

TimxHandle.Instance = TIM2;

TimxHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if ( HAL_TIM_Base_Init(&TimxHandle) != HAL_OK )

{

Error_Handler();

}

HAL_TIM_Base_Start_IT(&TimxHandle);

HAL_NVIC_SetPriority(TIMx_IRQn, 0, 1);

HAL_NVIC_EnableIRQ(TIMx_IRQn);

2. here are my configures for none working timers' interrupt:

/*########## Configure TIMy y = 1,9 ######################################*/

__TIMy_CLK_ENABLE();

TimyHandle.Init.Prescaler = 16400;

TimyHandle.Init.CounterMode = TIM_COUNTERMODE_UP;

TimyHandle.Init.Period = 2500;

TimyHandle.Instance = TIMy;

//TimyHandle.Channel = HAL_TIM_ACTIVE_CHANNEL_1; // it does not matter whether I set this

TimyHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if ( HAL_TIM_Base_Init(&TimyHandle) != HAL_OK )

{

Error_Handler();

}

HAL_TIM_Base_Start_IT(&TimyHandle);

HAL_NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, 0, 1);

HAL_NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);    // this make system hung

would you please help me for that.

now basically , I would need use at least 8 timers' interrupts. 

thanks for all of your

rose

0690X0000060LNDQA2.png
roseanne qiu
Associate II
Posted on June 21, 2018 at 23:22

Dear Dhenry:

further reading your response, I guess :

in my settings , i have period value for a timer, and then I could set 

channel = channel1|chnnel2...; 

period = n tickes; // I guess this is ticks, or period

in the timer interrupt,

suppose channel 1 has period n ticks , channel 2 has 2n ticks

1. check whether it is the timer I configure

2. check whether it is channel1, if so check its counting? (like n) if so, it is for channel1?

3. check whether it is channel2, if so check its counting (like 2n) if so, it is for channel2?

am I correct?

since I use HAL lib, I may need to read __HAL_TIM_GET_COUNTER(&TimxHandle) inside ISR

to get countings?

thanks 

roseanne

Posted on June 21, 2018 at 22:56

'

if not same, how could I do that?'

easy.

1) set up the timer to free run;

2) set up a compare channel, and pick its matchpoint to be the timer's current value + N ticks away;

3) in the compare ISR, advance the matchpoint by another N ticks away;

4) set a flag to indicate overflow, or run a quick user code.

the timer will have a period of N ticks.

you can do this for as many channels as there are output compare channels on a given timer.

basic principles here: 

https://wordpress.com/post/dannyelectronics.wordpress.com/4097

 

code examples here: 

https://github.com/dannyf00/My-MCU-Libraries---2nd-try/tree/master/STM32F1xx

  look for those timXoc.h/.c files, X=1, 2, 3, 4, ...
Posted on June 21, 2018 at 23:13

Dear Dhenry:

Thanks for your quick response!

I just went to your link and check the setting for the timer different channels. 

but I found you do not use HAL lib, I am using HAL lib,

I would like to know what Hal API to use, and also in Hal lib, there are timer structure:

============================================

typedef struct

{

TIM_TypeDef *Instance; /*!< Register base address */

TIM_Base_InitTypeDef Init; /*!< TIM Time Base required parameters */

HAL_TIM_ActiveChannel Channel; /*!< Active channel */

DMA_HandleTypeDef *hdma[7]; /*!< DMA Handlers array

This array is accessed by a @ref DMA_Handle_index */

HAL_LockTypeDef Lock; /*!< Locking object */

__IO HAL_TIM_StateTypeDef State; /*!< TIM operation state */

}TIM_HandleTypeDef;

=================================

I know how to set basic parameters, and channels, but do not know how to set what you mentioned.

especial to HAL API?

any one could give me examples for HAL lib?

thanks

rose