嵌入式软件中的延时函数

延时函数是嵌入式软件开发中必不可少的功能函数,在每个工程里都能找到它的踪影。虽然看起来不起眼,但在有些时序控制的场合,使用了一点点delay,往往能解决大问题。下面描述一下delay函数的几种实现。

中断延时实现

 U16 TimingDelay = 0;
void delay_Init(void)
{
    SysTick_Config(SystemFrequency / 1000); //1ms
}

void delay_DelayMs
 (
    U16 x       //延时的毫秒数
 )
 {
    TimingDelay = x;
    while(TimingDelay != 0);   
 }
void SysTick_Handler(void)
{
    if (TimingDelay > 0)
    {
        TimingDelay --;
    }
}

较为常用,借助系统滴答时钟中断,来实现较为精准的延时,延时精度可以通过设定中断周期来控制。但是也因为使用了中断,如出现中断方面的异常,容易造成while循环死循环,程序崩溃。就更不能在中断函数里使用。

while循环++的方法

#define COMPUTE_TIMES_1MS 10120
void delay_DelayMs
(
    U16 x       //延时的毫秒数
)
{
    u32 n;
    n = x*COMPUTE_TIMES_1MS;
    while(n > 0)
    {
        n --;
    }
}

此方法比较灵活,用于不需要很精确延时的场合。我们可以使用一个GPIO输出电平再用示波器测量的方式尽量准确的获得COMPUTE_TIMES_1MS的数值。

Gpio_low();
delay_DelayMs(100);
Gpio_high();
delay_DelayMs(100);
Gpio_low();

同样如果需要做非常小的延时,可以做需要次数的cpu指令次数

void delay_DelayCpuTimes
(
    U16 x
)
{   
    u32 i;
    for (i=0;i<x; i++)
    {
    }
}

使用nop()语句

void DelayUS(u32 time)
{
    while(time--)
    {
        __NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();
    }
}

一个__nop空指令的时间就是执行一条指令的时间,主频不一样,一次__nop的时间也不一样,可以使用理论计算的算出1us能执行多少次nop,也可以使用示波器测试的方法来测量。

操作系统的sleep函数

void TSK_SleepMs(uint32_t ms)
{
    vTaskDelay((configTICK_RATE_HZ * ms) / 1000);
}

在带操作系统的程序中(如freerots,ucos等),系统提供了专用的线程sleep函数,用作延时。注意sleep不要用在中断函数中。

结尾

今天分享下嵌入式系统中常用的延时函数。


在这里插入图片描述

扫描上方二维码关注“嵌入式案例Show”公众号,看更多嵌入式案例

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容