STM32 - SysTick timer explanation (code)

1, SysTick - Introduction to system timer

SysTick - system timer is a peripheral in CM3 kernel, embedded in NVIC. The system timer is a 24bit downward decreasing counter. The time of each count is 1/SYSCLK. Generally, we set the system clock SYSCLK equal to 72M. When the value of the reload value register decreases to 0, the system timer generates an interrupt to cycle back and forth.

Because SysTick is a peripheral of CM3 kernel, all microcontrollers based on CM3 kernel have this system timer, so that the software can be easily transplanted in CM3 microcontroller. The system timer is generally used for the operating system to generate time base and maintain the heartbeat of the operating system.

2, SysTick register introduction

SysTick - the system timer has 4 registers, which are briefly described below. When using SysTick to generate timing, only the first three registers need to be configured, and the last calibration register does not need to be used.


SysTick is a peripheral of the kernel. The relevant register definitions and library functions are in the kernel related library file core_cm3.h.

3, SysTick timing experiment

Function: use SysTick to generate 1s time base, and the LED flashes at 1s frequency.

Programming points

1. Sets the value of the reload register

2. Clears the value of the current value register

3. Configuration control and status register

SysTick_ The config() library function mainly configures three registers in systick: LOAD, VAL and CTRL.
When programming with the firmware library, we only need to call the library function SysTick_Config(). The formal parameter ticks is used to set the value of the reload register. The maximum value cannot exceed the value 224 of the reload register. When the value of the reload register decreases to 0, an interrupt is generated, and then the value of the reload register is reloaded and counted down, so as to cycle back and forth. Next, set the interrupt priority. Finally, configure the clock of the system timer to be equal to AHBCLK=72M to enable the timer and timer interrupt. In this way, the system timer is configured and a library function is completed.

//SysTick configuration library functions
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
    // Impossible reload value, out of range
    if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) {
        return (1UL);
    }

    // Set reload register
    SysTick->LOAD  = (uint32_t)(ticks - 1UL);

    // Set interrupt priority
    NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);

    // Set current value register
    SysTick->VAL   = 0UL;

    // Set the clock source of the system timer as AHBCLK=72M
    // Enable system timer interrupt
    // Enable timer
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                    SysTick_CTRL_TICKINT_Msk   |
                    SysTick_CTRL_ENABLE_Msk;
    return (0UL);
}

SysTick initialization function

 /**
* @brief Start the system tick timer SysTick
* @param nothing
* @retval nothing
*/
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms Interrupt once
* SystemFrequency / 100000 10us Interrupt once
* SystemFrequency / 1000000 1us Interrupt once
*/
if (SysTick_Config(SystemCoreClock / 100000)) {
/* Capture error */
while (1);
}
}

Calculation of SysTick timing time
When the interrupt time T INT is set, we can set a variable t to record the number of interrupts. That
The time to be timed can be calculated by multiplying the unit variable t by the interrupt time TINT.

SysTick timing function
Now we define a microsecond delay function with the parameter nTime, which is multiplied by the interrupt time
TINT will get the delay time we need, in which TINT has been set to 10us. About the specific of this function
Call to see the comments.

/*
us Delay program, 10us as a unit
Delay_us( 1 ) The delay achieved is 1 * 10us = 10us
*/
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;

while (TimingDelay != 0);
}

Function delay_ In us (), we wait for TimingDelay to be 0. When TimingDelay is 0, it means delay
From time to time. The variable TimingDelay is decremented in the interrupt function, that is, every time SysTick enters an interrupt, that is, 10us
TimingDelay decrements once.

//SysTick interrupt service function
void SysTick_Handler(void)
 {
TimingDelay_Decrement();
}

The interrupt reset function calls another function, TimingDelay_Decrement(), the prototype is as follows:

/*
Get beat program
 Interrupt function SysTick in SysTick_Handler() call
*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00) {
TimingDelay--;
}
}

The value of TimingDelay is equal to the value of nTime passed in the delay function. For example, if nTime=100000, the delay
The time is equal to 100000*10us=1s.

Main function

int main(void)
{
/* LED Port initialization */
LED_GPIO_Config();

/* Configure SysTick to interrupt once for 10us, and trigger the timing interrupt when the time expires,
*Enter stm32fxx_ Systick of it. C file_ Handler processing, timing by counting the number of interrupts
*/
SysTick_Init();

while (1) {

LED_ON;
Delay_us(100000); // 10000 * 10us = 1000ms

LED2_ON;
Delay_us(100000); // 10000 * 10us = 1000ms

LED3_ON;
Delay_us(100000); // 10000 * 10us = 1000ms
}
}

The LED and SysTick are initialized in the main function, and then the LED flashes at the frequency of 1s in a while loop.

Tags: stm32

Posted on Sun, 05 Sep 2021 22:43:15 -0400 by mcl