当前位置:网站首页>Learning record: understand systick system timer and write delay function
Learning record: understand systick system timer and write delay function
2022-07-06 15:32:00 【Bitter tea seeds】
Catalog
One 、Sys Tick Calculation of timing time
3、 ... and 、Sys Tick Interrupt priority
Four 、 Write the delay function
SysTick Tied to NVIC in , It's a 24 position Timer for , And can only decrease .
(NVIC It is a vector interrupt controller , It also contains MPU Control register of 、SysTick Timer and debugging control .)
And in the 《STM32 Chinese Reference Manual 》 in , Yes SysTick The introduction of is just a simple sentence :SysTick The calibration value is fixed to 9000, When SysTick The clock is set to 9MHz(HCLK/8 The maximum of ), produce 1ms Time base .
One 、Sys Tick Calculation of timing time
Let the time of a cycle count be t ;
Clk from CTRL Register configuration , The frequency is 72M and 9M
misc.c The system clock
If you choose SysTick_CLKSource_HCLK for 72M;
Otherwise, it would be SysTick_CLKSource_HCLK_Div8 for 9M;
/**
* @brief Configures the SysTick clock source.
* @param SysTick_CLKSource: specifies the SysTick clock source.
* This parameter can be one of the following values:
* @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
* @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
* @retval None
*/
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;
}
else
{
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
}
}
misc.h The system clock
/** @defgroup SysTick_clock_source
* @{
*/
/*/8, That is, select the kernel clock 9M*/
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
/*72M*/
#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
((SOURCE) == SysTick_CLKSource_HCLK_Div8))
t=RELOAD*(1/clk)
Clk( Clock interrupt )=72M when ,t=(72)×(1/72M)=1 us; //1 us Enter an interrupt NVIC
Clk( The clock )=72M when ,t=(72000)×(1/72M)=1 Ms; //1 ms Enter an interrupt NVIC
Convert units according to time :1 s=1000 ms=1000000 us=1000000000 ns
Two 、Sys Tick register
Sys Tick Register structure
core_cm3.h:
/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick
memory mapped structure for SysTick
@{
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */
} SysTick_Type;
Sys Tick Configure library functions
/**
* @brief Initialize and start the SysTick counter and its interrupt.
*
* @param ticks number of ticks between two interrupts
* @return 1 = failed, 0 = successful
*
* Initialise the system tick timer and its interrupt and start the
* system tick timer / counter in free running mode to generate
* periodical interrupts.
*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible reload The register of 24bit, The maximum value is 2^24*/
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register To configure reload The initial value of the ,'-1' Because when configuring , One has been consumed systick cycle */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts Configure interrupt priority as 1<<4-1=15, The priority is the lowest */
SysTick->VAL = 0; /* Load the SysTick Counter Value To configure counter The value of the counter */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer To configure systick The clock is 72M, To interrupt , Can make systick*/
return (0); /* Function successful */
}
NVIC_SetPriority function
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
else {
NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
}
3、 ... and 、Sys Tick Interrupt priority
1.STM32 Both the kernel and peripherals are used 4 Binary bits to indicate interrupt priority .
2. The grouping of interrupt priority is also applicable to the kernel and peripherals . When comparing , Just group and parse the four bits of the interrupt priority of the peripheral device of the kernel according to the interrupt priority of the peripheral device , That is to say, artificially divide preemptive priority and sub priority .
Four 、 Write the delay function
1. Write a delay function
bsp_SysTick.h The header file
#ifndef __SYSTICK_H
#define __SYSTICK_H
#include "stm32f10x.h"
void SysTick_Init(void);
void Delay_us(__IO u32 nTime);
#define Delay_ms(x) Delay_us(100*x) // Company ms
void SysTick_Delay_Us( __IO uint32_t us);
void SysTick_Delay_Ms( __IO uint32_t ms);
#endif
bsp_SysTick.c file
#include "bsp_SysTick.h"
#include "core_cm3.h"
#include "misc.h"
static __IO u32 TimingDelay;
/**
* @brief Start the system tick timer SysTick
* @param nothing
* @retval nothing
*/
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms Break once
* SystemFrequency / 100000 10us Break once
* SystemFrequency / 1000000 1us Break once
*/
// if (SysTick_Config(SystemFrequency / 100000)) // ST3.0.0 Library version
if (SysTick_Config(SystemCoreClock / 100000)) // ST3.5.0 Library version
{
/* Capture error */
while (1);
}
}
/**
* @brief us Delay program ,10us For a unit
* @param
* @arg nTime: Delay_us( 1 ) Then the delay is 1 * 10us = 10us
* @retval nothing
*/
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;
// Enable tick timer
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
while(TimingDelay != 0);
}
/**
* @brief Get the beat program
* @param nothing
* @retval nothing
* @attention stay SysTick Interrupt function SysTick_Handler() call
*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
#if 0
// This Firmware library functions stay core_cm3.h in
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
// reload The register is 24bit, The maximum value is 2^24
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
// To configure reload The initial value of the register
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
// Configure interrupt priority as 1<<4-1 = 15, The priority is the lowest
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
// To configure counter The value of the counter
SysTick->VAL = 0;
// To configure systick The clock is 72M
// To interrupt
// Can make systick
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0);
}
#endif
// couter reduce 1 Time for be equal to 1/systick_clk
// When counter from reload The value of is reduced to 0 When , For a cycle , If interrupt is turned on, the interrupt service program is executed ,
// meanwhile CTRL Of countflag Position meeting position 1
// The time of this cycle is reload * (1/systick_clk)
void SysTick_Delay_Us( __IO uint32_t us)
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000000);
for(i=0;i<us;i++)
{
// When the value of the counter decreases to 0 When ,CRTL Bit of register 16 I'll set 1
while( !((SysTick->CTRL)&(1<<16)) );
}
// close SysTick Timer
SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Delay_Ms( __IO uint32_t ms)
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000);
for(i=0;i<ms;i++)
{
// When the value of the counter decreases to 0 When ,CRTL Bit of register 16 I'll set 1
// Dangzhi 1 when , Reading this bit clears 0
while( !((SysTick->CTRL)&(1<<16)) );
}
// close SysTick Timer
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}
main.c
#include "stm32f10x.h"
#include "bsp_SysTick.h"
#include "bsp_led.h"
/*
* t : Timing time
* Ticks : How many clock cycles produce an interrupt
* f : clock frequency 72000000
* t = Ticks * 1/f = (72000000/100000) * (1/72000000) = 10us
*/
/**
* @brief The main function
* @param nothing
* @retval nothing
*/
int main(void)
{
/* LED Port initialization */
LED_GPIO_Config();
#if 0
/* To configure SysTick by 10us Break once */
SysTick_Init();
for(;;)
{
LED1( ON );
Delay_us(100000); // 100000 * 10us = 1000ms
//Delay_ms(100);
LED1( OFF );
LED0( ON );
Delay_us(100000); // 100000 * 10us = 1000ms
//Delay_ms(100);
LED0( OFF );
}
#else // Do not use interrupt , Use the method of query
for(;;)
{
LED1( ON );
SysTick_Delay_Ms( 1000 );
LED1( OFF );
LED0( ON );
SysTick_Delay_Ms( 1000 );
LED0( OFF );
}
#endif
}
Delay function library file
delay_init function
// Initialization delay function
// When using OS When , This function initializes OS The beat of the clock
//SYSTICK The clock is fixed to HCLK The clock
//SYSCLK: System clock frequency
void delay_init(u8 SYSCLK)
{
#if SYSTEM_SUPPORT_OS // If support is needed OS.
u32 reload;
#endif
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
//SysTick The frequency is HCLK
fac_us=SYSCLK; // Whether used or not OS,fac_us You need to use
#if SYSTEM_SUPPORT_OS // If support is needed OS.
reload=SYSCLK; // The number of counts per second Unit is K
reload*=1000000/delay_ostickspersec; // according to delay_ostickspersec Set the overflow time
//reload by 24 Bit register , Maximum :16777216, stay 72M Next , About us 0.233s about
fac_ms=1000/delay_ostickspersec; // representative OS The minimum unit that can delay
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;// Turn on SYSTICK interrupt
SysTick->LOAD=reload; // Every time 1/OS_TICKS_PER_SEC Second break once
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; // Turn on SYSTICK
#else
#endif
}
SysTick->CTRL Bit definition of ( Structure pointer )
SysTick-> VAL The definition of
delay_us function
// Time delay nus
//nus To delay us Count .
//nus:0~190887435( The maximum value is 2^32/[email protected]_us=22.5)
void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD; //LOAD Value
ticks=nus*fac_us; // The number of beats needed
told=SysTick->VAL; // Counter value at the time of first entry
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow<told)tcnt+=told-tnow;// Note here SYSTICK It's just a decreasing counter .
else tcnt+=reload-tnow+told;
told=tnow;
if(tcnt>=ticks)break; // For more than / Equal to the time to delay , The exit .
}
};
}
// Time delay nus
//nus: To delay us Count .
//nus:0~190887435( The maximum value is 2^32/[email protected]_us=22.5)
void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD; //LOAD Value
ticks=nus*fac_us; // The number of beats needed
delay_osschedlock(); // prevent OS Dispatch , Prevent interruptions us Time delay
told=SysTick->VAL; // Counter value at the time of first entry
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow<told)tcnt+=told-tnow; // Be careful SYSTICK Is a decrement counter .
else tcnt+=reload-tnow+told;
told=tnow;
if(tcnt>=ticks)break; // For more than / Equal to the time to delay , The exit .
}
};
delay_osschedunlock(); // recovery OS Dispatch
}
delay_ms function
// Time delay nms
//nms: To delay ms Count
void delay_ms(u16 nms)
{
u32 i;
for(i=0;i<nms;i++) delay_us(1000);
}
// Time delay nms
//nms: To delay ms Count
//nms:0~65535
void delay_ms(u16 nms)
{
if(delay_osrunning&&delay_osintnesting==0)// If OS Already running , And not in interruption
{
if(nms>=fac_ms) // The delay time is longer than OS The minimum time period of
{
delay_ostimedly(nms/fac_ms); //OS Time delay
}
nms%=fac_ms; //OS It is no longer possible to provide such a small delay , Delay in the normal way
}
delay_us((u32)(nms*1000)); // Normal mode delay
}
边栏推荐
- STM32學習記錄:輸入捕獲應用
- Pedestrian re identification (Reid) - Overview
- Servlet
- MySQL数据库(一)
- FSM和i2c实验报告
- MySQL数据库(五)视 图 、 存 储 过 程 和 触 发 器
- UCORE LaB6 scheduler experiment report
- How to rename multiple folders and add unified new content to folder names
- LeetCode#268. Missing numbers
- Your wechat nickname may be betraying you
猜你喜欢
Video scrolling subtitle addition, easy to make with this technique
[pytorch] simple use of interpolate
Pedestrian re identification (Reid) - Overview
Brief introduction to libevent
Leetcode notes - dynamic planning -day6
The wechat red envelope cover designed by the object is free! 16888
What is "test paper test" in software testing requirements analysis
Unpleasant error typeerror: cannot perform 'ROR_‘ with a dtyped [float64] array and scalar of type [bool]
ucore lab 2
ucore lab 6
随机推荐
How to rename multiple folders and add unified new content to folder names
C4D quick start tutorial - creating models
FSM和i2c实验报告
ucore lab6 调度器 实验报告
学习记录:理解 SysTick系统定时器,编写延时函数
What to do when programmers don't modify bugs? I teach you
Your wechat nickname may be betraying you
csapp shell lab
Programmers, how to avoid invalid meetings?
Maximum nesting depth of parentheses in leetcode simple questions
Threads and thread pools
Cadence physical library lef file syntax learning [continuous update]
软件测试方法有哪些?带你看点不一样的东西
软件测试有哪些常用的SQL语句?
软件测试面试要问的性能测试术语你知道吗?
Research Report on market supply and demand and strategy of China's medical chair industry
MySQL transactions
STM32學習記錄:輸入捕獲應用
Future trend and planning of software testing industry
Interview answering skills for software testing