利用系统滴答定时器编写延时函数

1.硬件为stm32f407vet6,外部8M时钟

2.微秒级延时函数最大延时99.86ms

函数实现: 

void Delay_Init(void) {

    SysTick->CTRL = 0; // 关闭SysTick

    SysTick->VAL = 0; // 清空当前计数值

    // 选择时钟源:默认分频HCLK/8,168MHz/8=21MHz

    SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk; // 若需更高精度,可移除分频(直接使用168MHz)

   /* 

      选择 HCLK 作为时钟源(不分频)

       SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;

       选择 HCLK/8 作为时钟源(分频)

       SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;

   */

}

void delay_us(uint32_t us) {

    // 计算计数值(168MHz下不分频:us*168;分频后21MHz:us*21)

    SysTick->LOAD = us * 21 - 1; // 分频21MHz,每us需21个周期,不分频168MHz,每us需168个周期

    SysTick->VAL = 0; // 重置计数器

    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 启动计数

    while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); // 等待计数完成

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // 关闭SysTick

}

void delay_ms(uint32_t ms) {

    while (ms--) {

        delay_us(1000); // 调用微秒级延时1000次

    }

}

优势

利用系统滴答定时器(SysTick)实现的延时函数具有以下核心优点:

1. 高精度与稳定性

- 硬件级计时:SysTick是Cortex-M内核集成的24位递减计数器,直接基于系统时钟(如STM32F407的168MHz)工作,计时精度可达微秒级。  

- 独立运行:SysTick独立于CPU核心,即使CPU处理其他任务,计时仍持续进行,不受代码阻塞或中断抢占的显著影响。  

- 低误差:相比软件循环延时(误差±5%),SysTick的误差可控制在±0.1%以内。

2. 低资源占用与高效性

- 无需额外外设:SysTick是内核内置功能,无需配置通用定时器(如TIM2),节省硬件资源。  

- 低CPU占用:采用中断或轮询方式时,CPU可在延时期间执行其他任务(如多任务调度),而非空转等待。  

- 高效的中断处理:SysTick中断优先级固定且独立,触发周期稳定,适合作为实时操作系统(RTOS)的时间基准。

3. 灵活性与易用性

- 时钟源可选:支持HCLK(不分频)或HCLK/8两种时钟源,适应不同精度与功耗需求。例如,168MHz下不分频可提供微秒级延时,分频后适合低功耗场景。  

- 兼容性强:HAL库已封装`HAL_Delay()`函数,用户无需手动配置寄存器即可快速实现毫秒级延时。  

- 多场景适用:既可用于简单延时(如LED闪烁),也可支持复杂任务调度(如FreeRTOS的时间片轮转)。

 4. 代码简洁与可维护性

- 标准化接口:通过`SysTick_Config()`等函数即可完成初始化,代码量少且易于移植。  

- 避免优化干扰:使用硬件计数器而非软件循环,编译器优化(如空循环删除)不会影响延时精度。  

- 易于调试:通过读取`SysTick->VAL`寄存器可直接验证当前计数值,便于调试时序问题。

 5. 低功耗特性

- 动态功耗控制:在分频模式下(如HCLK/8),SysTick的时钟频率降低,减少动态功耗。  

- 与其他低功耗模式兼容:在延时期间,若结合CPU睡眠模式(如WFI指令),可进一步降低系统功耗。

 总结

SysTick延时函数凭借其高精度、低资源占用和内核级集成特性,成为STM32开发中的首选延时方案。尤其在实时操作系统、传感器时序控制等对时间敏感的场景中,其优势更为显著。如需更高灵活性(如纳秒级延时),可结合DWT计数器或通用定时器扩展功能。

关于 SysTick计数器溢出问题(核心原因)  


现象: delay_us(1000000)  试图延时1秒(1,000,000μs),但实际表现接近1ms。
原因:
 
SysTick是 24位递减计数器,最大计数值为  0xFFFFFF (即16,777,215)。
 
当系统时钟为168MHz时, LOAD 值计算为  1,000,000 * 168 - 1 = 167,999,999 ,远超24位最大值,导致 高位截断,实际加载值变为  167,999,999 & 0xFFFFFF = 16,777,215 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值