延迟功能通常用于微控制器编程中。
最常用的是微秒delay_us()和毫秒delay_ms()。
本文基于STM32F207,介绍了以4种不同方式实现的延迟功能。
普通延迟当每个人都在51单片机中时,这种延迟方法应该是最早的延迟功能。
这是相对简单的。
让微控制器做一些微不足道的工作来打发时间。
它通常通过循环来实现。
在某些编译器下,将对代码进行优化,从而降低准确性。
它用于一般延迟,并且对精度不敏感。
应用场景。
//微秒延迟void delay_us(uint32_t delay_us){volatile unsigned int num; volatile unsigned int t; for(num = 0; num& lt; delay_us; num ++){t = 11; while(t!= 0){t--;}}} //毫秒延迟void delay_ms(uint16_t delay_ms){volatile unsigned int num;对于(num = 0; num& lt; delay_ms; num ++){delay_us(1000); }}上述项目的源代码存储库:https://github.com/strongercjd/STM32F207VCT6/tree/master/02-Template(注意:官方帐户不支持外部链接,请将该链接复制到浏览器中进行下载)定时器中断定时器具有较高的精度,我们可以配置定时器中断,例如,配置一次1ms的中断,然后间接判断中断的数量,以达到准确延迟的目的。
可以保证此方法的准确性,但是系统总是在中断,这不利于在其他中断中调用此延迟函数。
一些高精度的应用场景不合适,例如正在输出其他外围设备,并且不允许任何中断。
。
可以使用STM32的任何定时器。
让我们以SysTick计时器为例进行介绍:初始化SysTick计时器:/ *将SysTick配置为1ms * / RCC_GetClocksFreq(& amp; RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);中断服务函数:无效SysTick_Handler(void){TimingDelay_Decrement();} void TimingDelay_Decrement(void){if(TimingDelay!= 0x00){TimingDelay--; }}延迟函数:void Delay(__ IO uint32_t nTime){TimingDelay = nTime; while(TimingDelay!= 0);}上述项目的源代码存储库:https://github.com/strongercjd/STM32F207VCT6/tree/master/02-Template(注意:官方帐户不支持外部链接,请复制链接到浏览器以进行下载)查询计时器为了解决计时器频繁中断的问题,我们可以使用计时器,但是禁用中断并使用查询方法进行延迟。
这样可以解决频繁中断的问题,并保证准确性。
可以使用STM32的任何定时器。
让我们以SysTick计时器为例进行介绍。
STM32的CM3核心处理器内部包含一个SysTick计时器。
SysTick是一个24位倒数计时器。
当它计数到0时,它将自动从RELOAD寄存器中重新加载时序初始值。
只要不清除SysTick控制和状态寄存器中的启用位,它就永远不会停止。
SYSTICK时钟固定为HCLK时钟的1/8。
在这里,我们选择内部时钟源120M,因此SYSTICK时钟为(120/8)M,即SYSTICK定时器以(120/8)M的频率减少。
SysTick主要包含4个寄存器,例如CTRL,LOAD,VAL和CALIB。
▼CTRL:控制和状态寄存器▼LOAD:自动重载除数值寄存器▼VAL:当前值寄存器▼CALIB:不使用校准值寄存器,不再引入代码void delay_us(uint32_t nus){uint32_t temp; SysTick-& gt; LOAD = RCC_Clocks.HCLK_Frequency / 1000000/8 * nus; SysTick-& gt; VAL = 0X00; //清除计数器SysTick-> CTRL = 0X01; //启用,减小到零是没有作用,请使用外部时钟源CTRL; //读取当前的倒计时值)while((temp& amp; 0x01)& amp; amp;(!(temp& amp;(1& lt;& lt; 16)))); / /等待时间达到SysTick-> CTRL = 0x00; //关闭计数器SysTick-> VAL = 0X00; //清除计数器)void delay_ms(uint16_t nms){uint32_t temp; SysTick-> LOAD = RCC_Clocks.HCLK_Frequency / 1000/8 * nms; SysTick-& gt VAL = 0X00; //清除计数器SysTick-> CTRL = 0X01; //启用,减小到零是没有作用,请使用外部时钟源CTRL; //读取当前倒计时值)while((temp& amp; 0x01)& amp; amp;(!(temp& amp;(1& lt& lt; 16))))); //等待时间达到SysTick-CTRL = 0x00; //关闭计数器SysTick-& gt VAL = 0X00; //清空计数器}上面的项目源代码存储库:https://github.com/strongercjd/STM32F207VCT6/tree/master/04-Delay(注意:官方帐户不支持外部链接,请将链接复制到浏览器下载)汇编指令如果系统硬件资源紧张,或者没有提供其他计时器,并且您不希望方法1的普通延迟,则可以使用汇编指令进行延迟,