cancel
Showing results for 
Search instead for 
Did you mean: 

Read Systick Timer Value Directly for 1ms Timebase

EPala.2
Associate III

Hi, I am working on a project on the STM32H730 that runs a high priority audio interrupt thread as well as a lower priority asynchronous loop for user interface processing and a 1ms SysTick interrupt for user interface processes that need some accuracy in the timing.

I'm running into an issue where if my audio processing interrupt takes longer than 1ms (as is the case doing intensive processing at a 32kHz sample rate with a 128 sample buffer size) to execute SysTick interrupts no longer happen reliably once per ms. 

I imagine I can recreate this functionality by setting a timer to increment once per millisecond independent of the CPU and referencing this value whenever I need an accurate time reference. 

 

What function can I call to get the value of SysTick directly to compare to a global timer variable? Does this sound like the right approach? 

17 REPLIES 17
PGump.1
Senior III

Hi,

Are you using HAL and/or a RTOS?

Kind regards
Pedro

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.
Karl Yamashita
Lead III

You can change the interrupt priorities for each interrupt. Right now they are all defaulted to 0.

KarlYamashita_0-1728951600414.png

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

HAL

I don't necessarily want to set the 1ms tick function to a higher priority than the audio routine. The audio processing is very runtime critical so having a fully independent timer variable I can simply reference would work a lot better. 

I understand I could probably make the 1ms tick function just increment the global timer variable with no other processing, and do anything relying on the millisecond time base in the asynchronous loop, but this would be functionally the same as having a fully independent timer peripheral increment once per 1ms while also adding interrupt overhead to my program. Seems more ideal in the long term to set it up with the independent timer and not use an interrupt.

Hi,

You'll most likely find that HAL is putting an overhead into your process you can't afford...

I suggest using one of the hardware timers instead for your 1mS. Set the timer it up with MX using either HAL or LL, but use the timer's registers directly in your main() loop.

I hope that helps.

Kind regards
Pedro

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.

Yes, so my instinct is correct that using the independent hardware timer is the right approach. 

Can you help with the second part of my question, what syntax do I use to access these timer values? Is there any way I can just access the value of the SysTick timer (which is already set up to increment once per ms).

Could you divide down TIM2 or TIM5, via prescaler, so they free run at some rate you can use instead of SysTick?

The Prescaler is only 16-bit, but you might be able to select the clocking source, or APB dividers, to get you to around 64 MHz, that you could divide down to 1 KHz, and have HAL_GetTick read the TIMx->CNT ?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi,

The SysTick is a global variable "uwTick" (uint 32 bit).

Or, if using you an independent timer you will need to :-

       MX_TIMx_Init();      // Initialise the timer (Use MX for this)
       HAL_Timer_Start();  // something like that to start the timer. (I don't use HAL, I'm NOT familiar with all its functions).

       while (1) {      // main loop
            ...
            tick = TIMx->CNT;    // to get the current count
           ...
       }

If you want to browse the HAL functions, look in "/project_name/Drivers/STM32xxxx_HAL_Driver/Src/stm32xxxx_hal_tim.c"

I hope this helps.

Kind regards
Pedro

 

AI = Artificial Intelligence, NI = No Intelligence, RI = Real Intelligence.

Is there an easy way to calculate the frequency or period of the timer? The options CubeMX gives for this are rather limited to say the least:

As you can see, I can select between 3 clock sources but there's no indication of what frequencies these are running at, also no indication of the eventual resulting frequency after the prescaler, the clock ui also makes it totally unclear which of the many internally generated clock values are being used as the "Internal Clock".

I also am unable to search for anything in the clock configuration tab, my only option is to squint at this super dense graph while looking for information that I don't even know will be there.

EPala2_2-1729190756362.png

 

EPala2_1-1729190728014.png