SysTick Timer
1. Function
The SysTick timer is a simple timer that is available in all CM3\CM4 core chips. The SysTick timer is often used for delay and is used as the system clock when a real-time system is used.
Whether used as a delay or as a system heartbeat clock, SysTick can do the job without too complicated functions.
2. Implementation Principle
The SysTick timer is a 24-bit countdown. When the countdown reaches 0, the value in the RELOAD register is used as the initial value of the timer. At the same time, an interrupt can be generated at this time (exception number: 15).
For example, if the value of RELOAD is 999, then when the countdown reaches 0, it will continue to count down from reset to 999.
As long as the enable bit in the SysTick control and status register is not cleared, it will never stop and will continue to work even in sleep mode.
3. SysTick register (defined in core_cm3.h, all M3 core microcontrollers are the same)
#define SysTick ((SysTick_Type *) SysTick_BASE)
#define SysTick_BASE (SCS_BASE + 0x0010)
#define SCS_BASE (0xE000E000)
typedef struct
{
__IO uint32_t CTRL; // Control and status register
__IO uint32_t LOAD; // Reload value register
__IO uint32_t VAL; // Current count value register
__I uint32_t CALIB; // Calibration register
} SysTick_Type;
SysTick->CTRL: (can be set via SysTick_CLKSourceConfig() function)
COUNTFLAG(16)R: Count flag
When SysTick counts to 0, this bit is set to 1 by hardware, and when this bit is read, it is cleared to 0 by hardware.
CLKSOURCE(2)R/W: Clock source setting
1 = External clock source (STCLK) (1/8 of AHB bus clock (HCLK/8))
0 = Core clock (FCLK) (frequency of AHB bus clock (HCLK))
TICKINT(1)R/W: interrupt enable bit
1 = Generate a SysTick exception request when SysTick counts down to 0
0 = No action when count reaches 0
ENABLE(0)R/W: SysTick timer enable bit
(When the interrupt is enabled, you need to pay attention to the void SysTick_Handler(void) function)
SysTick_Type->LOAD: (SysTick_Config() function sets this register)
RELOAD(23:0)R/W: Reload value register
When SysTick reaches 0, the value will be reloaded
SysTick_Type->VAL: (SysTick_Config() function sets this register)
CURRENT(23:0)R/Wc: Current count value register
When read, it returns the current countdown value, and writing it clears it to zero, also clearing the COUNTFLAG flag in the SysTick Control and Status Register.
4. Library function analysis
misc.c
-------------------------------------------------- --------------------------------
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
((SOURCE) == SysTick_CLKSource_HCLK_Div8))
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
/* Check the parameters */
assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
{
SysTick->CTRL |= SysTick_CLKSource_HCLK; // Set CLKSOURCE to 1
}
else
{
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; // Set CLKSOURCE to 0
}
}
core_cm3.c
-------------------------------------------------- --------------------------------
#define SysTick_LOAD_RELOAD_Pos 0
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)
typedef enum IRQn
{
//...
SysTick_IRQn = -1,
//...
}IRQn_Type;
#define __NVIC_PRIO_BITS 4
#define SysTick_CTRL_CLKSOURCE_Pos 2
#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos)
#define SysTick_CTRL_TICKINT_Pos 1
#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos)
#define SysTick_CTRL_ENABLE_Pos 0
#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos)
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
// Set the count value to ticks - 1
// Reason 1: The video says that it takes time to execute these codes, so reduce one beat
// Reason 2: I think it is because SysTick counts down to 0. For example, if it is set to 1000, the range should be 999 ~ 0.
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
// Set interrupt priority
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
SysTick->VAL = 0;
// Set the clock source to the external clock source, enable the interrupt, and enable the SysTick timer
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0);
}
5. Delay Application
1. Interrupt mode
static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
/* Interrupt service function */
void SysTick_Handler(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
int main(void)
{
// ...
if (SysTick_Config(SystemCoreClock / 1000)) // Note that the systick clock here is HCLK and the interrupt interval is 1ms
{
while (1);
}
while(1)
{
Delay(200); //2ms
// ...
}
}
SysTick_Config(SystemCoreClock / 1000): (The original code assumes that the clock source is HCLK)
The setting here is 72000000Hz / 1000 = 72000 ticks, which means SysTick starts counting down from (72000-1).
An interrupt is triggered every time 72,000 beats are counted down.
The duration of one beat is: 72000000 / 72000 = 1000us == 1ms
SysTick_Config((SystemCoreClock / 8000000) * 1000 * 1):
SysTick_Config() will set the clock source to HCLK/8, so the parameters in the above code cannot be used in actual applications.
SystemCoreClock / 8000000: 1us beat number
1us beats * 1000: then 1ms beats
1ms beat number * 1: Set a SysTick interrupt of 1ms, that is, count down from ((SystemCoreClock / 8000000) * 1000 * 1) - 1.
2. Polling method
static u8 fac_us=0; //us delay multiplier
static u16 fac_ms=0; //ms delay multiplier
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //Select external clock HCLK/8
fac_us = SystemCoreClock/8000000; // 1/8 of the system clock 1us = 72000000 / 8000000 = 9 beats
fac_ms = (u16)fac_us*1000; // 1ms requires 9 * 1000 = 9000 beats
}
//Delay nus microseconds
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //Time loading
SysTick->VAL=0x00; //Clear the counter
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //Start countdown
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //Wait for time to arrive
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Close the counter
SysTick->VAL =0X00; //Clear the counter
}
//Delay nms
//Note the range of nms
//SysTick->LOAD is a 24-bit register, so the maximum delay is:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK is in Hz, nms is in ms
//Under 72M conditions, nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //Time loading (SysTick->LOAD is 24bit)
SysTick->VAL =0x00; //Clear the counter
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //Start countdown
do
{
temp=SysTick->CTRL;
//Wait for the time to arrive. Here is a little trick. Check the SysTick enable bit through (temp&0x01) to avoid the Systick timer being turned off and causing an infinite loop.
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off the counter
SysTick->VAL =0X00; //Clear the counter
}
Previous article:Setting of sysTick in STM32
Next article:Problems and solutions of STM32 Systick timer in realizing 1us delay
Recommended ReadingLatest update time:2024-11-15 15:49
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- EEWORLD University ----TI Precision Labs - Operational Amplifiers: 15 Comparator Applications
- system console
- STM32MP157A-DK1 Evaluation (5) STM32MP Linux System Boot Process
- How to combine the main program + boot program into one configuration for the programmer when programming Renesas chip with PG-FP5
- E220-400TBL-01 lora module wireless test board + 02Lora learning
- Discussion on the protection circuit of vehicle terminal power supply
- 100% Earn E-Coins or Red Packets: Tektronix will help you solve USB development and testing problems. Download, complain/share experiences to win good gifts
- Is it difficult to draw a switch power board?
- 【NXP Rapid IoT Review】 NO5. Development Kit Hardware Module Review
- Does anyone know how to connect the windings of a 6N4P PMSM?