单片机自定义延时函数Delay取值详解

我们想实现一个定时延时函数,在单片机里并没有什么sleep,需要我们自己实现。

延时函数跟 晶振频率 有很大的关系,因为晶振频率影响程序执行速度。

1、打开Keil 4 - Target Options - Target - Xtal(MHz) -里填写 你单片机 的晶振频率,如我的单片机晶振频率是 11.0592 就填 11.0592

2、创建c文件,编写函数

void Delay_Us(INT16U us){
    while(us--);
}

3、在main函数里调用它

Delay_Us(1); 
Delay_Us(2);
Delay_Us(3);
Delay_Us(100);
_nop_();

4、编译,然后Ctrl + F5 Debug运行,在每次Delay_Us 位置记录当前时间

依次记录到_nop_(); 最后停止debug,计算Delay_Us(2) - Delay_Us(1)    的时间,这个时间也就是Delay_Us(1)的执行时间,也可以认为是进入Delay_Us函数所占用的时间(函数跳转 、返回都需要时间的,while(1--)  其实没执行while循环),我这里结果是27.13微秒(Us)

然后计算Delay_Us(3) - Delay_Us(2)的时间,也就是Delay_Us(2)的执行时间,我这里是 36.89, 用36.89-27.13 =9.76 ,这个9.76 就是while  循环1次所需要的时间 。

接下来,而是推算Delay_Us(100) - Delay_Us(3),也就是 Delay_Us(3)的执行时间: 9.76 *2  + 27.13 = 46.65  , 9.76 *2也就是while执行两次循环所需要的时间 + 1次 函数进入、执行 、返回占用的时间 = 总执行时间,这个46.65和46.66基本吻合,我这里不知道为什么误差0.01 us ,不过问题不大,可以接受。

同理,我也可以计算 Delay_Us(100) 执行时间: 9.76 * 99 + 27.13 = 993.37 

5、在做DS18B20温度传感器,我们初始化需要拉低控制总线480us毫秒以上,那么Delay_Us参数该如何填写呢?

(480 - 27.13) / 9.76 = 47(向上取整,不要取46,拉低480us是 最低值,不能少,所以要向上取整) ,需要47次while循环  ,另外+1次 进入函数、执行、跳转的时间 47 + 1 = 48 , Delay_Us(48)就刚刚够了!  反向算下对不对: 47 *9.76 + 27.13 = 485.85us。 保险起见,我可以多写点50 也行

看有些人和我同样的开发板 和晶振 需要 Delay_Us(75)才够 拉低480us,可能跟我这里设置了: Option Target - Target - Memory Model - Large:variables in XDATA 有关系

发布了106 篇原创文章 · 获赞 204 · 访问量 128万+

猜你喜欢

转载自blog.csdn.net/ab6326795/article/details/100170094