STM32高精度延时实现: SysTick 定时器与普通延时法

需积分: 46 45 下载量 186 浏览量 更新于2024-09-11 1 收藏 31KB DOCX 举报
"本文主要介绍了在STM32开发中实现精确延时的两种常见方法:普通延时法和SysTick定时器延时法,并详细解释了这两种方法的原理和实现代码。" STM32作为一款广泛应用的微控制器,其延时功能在许多应用中都至关重要。精确延时能够确保程序按照预期的时间间隔执行特定任务,例如在LED闪烁、传感器采样或通信协议中。以下是STM32精确延时的详细解析: 1. 普通延时法 这种方法通常通过循环计数来实现,代码简单易懂。例如给出的`delay_us()`和`delay_ms()`函数,通过设置一个内部循环计数器`i`,并不断递减,达到延迟的效果。然而,这种方法的精确度依赖于CPU的运行速度和编译优化,因此在不同环境下可能产生误差。此外,这种方法占用CPU资源较高,因为它在整个延时期间持续执行循环。 ```c // 粗略的微秒级延时函数 void delay_us(u16 time) { u16 i = 0; while (time--) { i = 10; // 自己定义 while (i--); } } // 毫秒级的延时函数 void delay_ms(u16 time) { u16 i = 0; while (time--) { i = 12000; // 自己定义 while (i--); } } ``` 2. SysTick定时器延时 SysTick是Cortex-M3内核自带的一个24位倒计数定时器,它在每个系统时钟周期后减一,直到达到0时会触发中断并自动重装载初始值。这种方式提供了一种更精确且低开销的延时方法。 - 中断方式: 首先,通过`SysTick_Config()`函数配置SysTick,例如设置为每1ms中断一次。然后,定义一个全局变量`time_delay`来存储要延迟的时间。在中断服务函数中,每次中断时递减`time_delay`,直到其变为0,完成延时。 ```c volatile unsigned long time_delay; // 延时时间,全局变量 // 延时n_ms void delay_ms(volatile unsigned long nms) { // SYSTICK分频--1ms的系统时钟中断 if (SysTick_Config(SystemFrequency / 1000)) { while (1); // 错误处理 } time_delay = nms; // 读取定时时间 while (time_delay); SysTick->CTRL = 0x00; // 关闭计数器 SysTick->VAL = 0X00; // 清空计数器 } // 延时nus void delay_us(volatile unsigned long nus) { // SYSTICK分频--1us的系统时钟中断 if (SysTick_Config(SystemFrequency / 10000)) { while (1); // 错误处理 } // ... 其他实现细节 } ``` 使用SysTick定时器的优点在于,它可以独立于CPU运行,且不受中断或任务调度的影响,从而提供更为精确的延时。然而,这种方法需要对Cortex-M3的内核特性有一定了解,并且需要正确计算系统时钟频率。 总结来说,STM32精确延时可以根据项目需求选择普通延时法或SysTick定时器延时法。对于对时间精度要求不高的场景,可以使用普通延时法;而对精度有较高要求或者希望节省CPU资源的应用,则应优先考虑SysTick定时器延时法。在实际应用中,开发者需要根据具体需求和硬件资源来权衡选择。