STM32_关于系统systick定时器延时的delay文件

本文介绍了STM32的SysTick定时器工作原理,以及如何在UCOSII操作系统下,通过时钟摘取法实现delay_us和delay_ms功能,同时保持SysTick为系统提供时钟节拍。文章详细讲解了操作系统的3个宏定义和4个相关函数,以及delay_init和delay_us函数的实现细节。

CM4 内核的处理和 CM3 一样,内部都包含了一个 SysTick 定时器,SysTick 是一个 24 位的倒计数定时器,当计到 0 时,将从 RELOAD 寄存器中自动重装载定时初值。只要不把它在 SysTick 控制及状态寄存器中的使能位清除,就永不停息。

delay 文件夹内包含了 delay.c 和 delay.h 两个文件,这两个文件用来实现系统的延时功能,其中包含 7 个函数:
-下面4 个函数,仅在支持操作系统(OS)的时候,需要用到
void delay_osschedlock(void);   
void delay_osschedunlock(void); 
void delay_ostimedly(u32 ticks); 
void SysTick_Handler(void);   

-下面 3 个函数,则不论是否支持 OS 都需要用到。
void delay_init(u8 SYSCLK); 
void delay_ms(u16 nms);   
void delay_us(u32 nus); 

以 UCOSII 为例,介绍如何实现操作系统和我们的 delay 函数共用 SysTick 定时器
首先,我们简单介绍下 UCOSII 的时钟:ucos 运行需要一个系统时钟节拍(“心跳”),而这个节拍是固定的(由 OS_TICKS_PER_SEC 宏定义设置),比如要求 5ms 一次(即可设置:OS_TICKS_PER_SEC=200),在 STM32 上面,一般是由 SysTick 来为 ucos 提供时钟节拍,也就是 systick要设置为 5ms 中断一次,而且这个时钟一般是不能被打断的(否则就不准了)。
在 ucos 下 systick 不能再被随意更改,如果我们还想利用 systick 来做 delay_us 或者delay_ms 的延时,就必须利用时钟摘取法。以 delay_us 为例,比如delay_us(50),在刚进入 delay_us 的时候先计算好这段延时需要等待的 systick 计数次数,这里为 50 * 21次(假设系统时钟为 168Mhz,因为 systick 的频率为系统时钟频率的 1/8,那么 systick每增加 1,就是 1/21us),然后我们就一直统计 systick 的计数变化,直到这个值变化了 50*21,一旦检测到变化达到或者超过这个值,就说明延时 50us 时间到了。这样,我们只是抓取 SysTick计数器的变化,并不需要修改 SysTick 的任何状态,完全不影响 systick 作为 UCOS 时钟节拍的功能,这就是实现 delay 和操作系统共用 SysTick 定时器的原理。

操作系统支持的3宏定义及4相关函数

当需要 delay_ms 和 delay_us 支持操作系统(OS)的时候,我们需要用到 3 个宏定义和 4个函数

//本例程仅作 UCOSII 和 UCOSIII 的支持,其他 OS,请自行参考着移植 
					//支持 UCOSII //  
#ifdef    OS_CRITICAL_METHOD     
//OS_CRITICAL_METHOD 定义了,说明要支持 UCOSII        
#define delay_osrunning   OSRunning     		 //OS 是否运行标记,0,不运行;1,在运行 
#define delay_ostickspersec  OS_TICKS_PER_SEC    //OS 时钟节拍,即每秒调度次数 
#define delay_osintnesting    OSIntNesting       //中断嵌套级别,即中断嵌套次数 
#endif   
					//支持 UCOSIII//
#ifdef    CPU_CFG_CRITICAL_METHOD       
  //CPU_CFG_CRITICAL_METHOD 定义了,说明要支持 UCOSIII   
#define delay_osrunning   OSRunning      //OS 是否运行标记,0,不运行;1,在运行 
#define delay_ostickspersec  OSCfg_TickRate_Hz  //OS 时钟节拍,即每秒调度次数 
#define delay_osintnesting    OSIntNestingCtr    //中断嵌套级别,即中断嵌套次数 
#endif 

//us 级延时时,关闭任务调度(防止打断us级延迟) 
void delay_osschedlock(void) 
{
   
    
#ifdef CPU_CFG_CRITICAL_METHOD     //使用 UCOSIII 
  OS_ERR err;   
  OSSchedLock(&err
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值