STM32 - Delay延时函数

在使用STM32编程时,经常会用到延时,STM32 C3和C4内核,提供了一个非常简单的定时器 SysTick,可以很好的帮助做定时

1. SysTick

1.1 简介

SysTick定时器(System tick timer,系统滴答定时器),常用来做 延时系统的心跳时钟
这样可以节省MCU资源,不用浪费一个定时器。

SysTick定时器就是系统滴答定时器,一个24位倒计数定时器,计数到0时将从RELOAD寄存器中自动重装载定时器初值。
只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式也能工作。

SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号为15)。
SysTick中断的优先级也可以设置

1.2 寄存器配置

SysTick定时器一共有四个相关寄存器:

CTRL     SysTick 控制和状态寄存器 
LOAD     SysTick 自动重装载除值寄存器   
VAL      SysTick 当前值寄存器 
CALIB    SysTick 校准值寄存器(不常用)

SysTick->CTRL 的各位定义如图

SysTick-> LOAD 的定义如图

SysTick-> VAL 的定义如图

2. 延时函数

1) delay_init()

/* 初始化延迟函数
 * 当使用 OS 的时候,此函数会初始化 OS 的时钟节拍
 * SYSTICK 的时钟固定为 AHB 时钟的 1/8
 * SYSCLK:系统时钟频率
 */

void delay_init(u8 SYSCLK) {
#if SYSTEM_SUPPORT_OS //如果需要支持 OS.
	u32 reload;
#endif

	SysTick->CTRL&=~(1<<2); //SYSTICK 使用外部时钟源(HCL/8)
	fac_us=SYSCLK/8; //不论是否使用 OS,fac_us 都需要使用
	
#if SYSTEM_SUPPORT_OS //如果需要支持 OS.
	reload=SYSCLK/8; //每秒钟的计数次数 单位为 M 
	reload*=1000000/delay_ostickspersec; //根据 delay_ostickspersec 设定溢出时间

	//reload 为 24 位寄存器,最大值:16777216,在 168M 下,约合 0.7989s 左右
	fac_ms=1000/delay_ostickspersec; //代表 OS 可以延时的最少单位 
	SysTick->CTRL|=1<<1; //开启 SYSTICK 中断
	SysTick->LOAD=reload; //每 1/delay_ostickspersec 秒中断一次
	SysTick->CTRL|=1<<0; //开启 SYSTICK 
#else
	fac_ms=(u16)fac_us*1000; //非 OS 下,代表每个 ms 需要的 systick 时钟数 
#endif
}
SysTick 是 MDK 定义了的一个结构体(在 core_m4.h 里面),里面包含 CTRL、LOAD、VAL、
CALIB 等 4 个寄存器,

2)delay_us(u32 n_us)

//延时 nus
//nus 为要延时的 us 数.
//注意:nus 的值,不要大于 798915us 
void delay_us(u32 nus) {
	u32 temp; 
	
	if(nus==0)
		return; //nus=0,直接退出
		
	SysTick->LOAD=nus*fac_us; //时间加载 
	SysTick->VAL=0x00; //清空计数器
	SysTick->CTRL=0x01 ; //开始倒数
	do {
		temp=SysTick->CTRL;
	} while((temp&0x01)&&!(temp&(1<<16)));//等待时间到达 
	
	SysTick->CTRL=0x00; //关闭计数器
	SysTick->VAL =0X00; //清空计数器
}

实现一次延时 nus 的操作

- 先把要延时的 us 数换算成 SysTick 的时钟数
- 然后写入 LOAD 寄存器
- 然后清空当前寄存器 VAL 的内容,
- 再开启倒数功能
- 等到倒数结束,即延时了 nus。最后关闭 SysTick,清空 VAL 的值。,

Notice:

nus值不能太大,必须保证 nus<=(2^24)/fac_us,否则将导致延时时间不准确。
这里特别说明一下:temp&0x01,这一句是用来判断 systick 定时器是否还处于开启状态,可以防止 systick 被意外关闭导致的死循环。
posted @ 2023-01-08 17:51  Jimmy_Nie  阅读(3285)  评论(0编辑  收藏  举报