51单片机延时程序的延时时间计算

        最近在上单片机原理及应用课程,做实验的时候遇到了软件延时程序如何计算延时时间的问题,经过一阵摸索终于领悟到其中奥秘......耶(比耶)。 延时函数是使用STC-ISP生成的,晶振为12MHz,指令集是STC-Y1(即89系列),使用do while()循环实现软件精确延时。下面讲解一下其中的延时时间是如何计算的。 

1. 首先我们先设置断点是程序运行到进入delay_10ms()函数前,可以在图1右下角看到此时程序运行时间为0.00040800sec,此时我们看向反汇编窗口(Disassembly)。请注意圈出来的“LCALL delay_10ms”汇编指令,程序运行到代码“ int a=100 ”并完成赋值后往下运行遇到delay_10ms(),子程序调用指令LCALL 完成对delay_10ms()的调用,该指令消耗24个时钟周期,即 t1=2us。

 

图1

2. 接着点击调试中的单步执行按钮,使程序转到delay_10ms()中,图2可以看到,首先执行“ MOV R7,#0x14”(即 i=20),接着执行“MOV R6,#0x71”,查STC-ISP指令表可知将立即数赋值给寄存器指令“MOV Rn #data”消耗12个时钟周期,故上述两部共消耗 t2=2us。

 图2

3. i,j赋值完再接着往下是执行do{}里面的内容“while(--j)”,“DJNZ  R6 , C:005D”指令的意思是寄存器R6里面的内容减1不为0则转移到“C:005D”处,即继续执行j自减。DJNZ指令消耗24个时钟周期,一共执行113次,即113 X 2us = 226us 。

4. 当j从113自减到0后,不满足DJNZ条件,则程序继续往下执行“ while(--i)”,即判断do while()的条件。该代码对应汇编指令为“ DJNZ  R7 , C:005D”,即i=20,自减1为19,不为0则转移到C:005D,继续执行j自减。注意,接下来的步骤很容易算错,很多人可能误以为j会再次从113开始自减,但实际不是的,前面存放 j=113 的寄存器R6从113自减到0后,此时再次自减 将从256开始,因为寄存器值从0开始减1后将会变成11111111,即256。这样,整个循环时间就很容易得出来了:t3 = 113 X 1 X 2us + 256 X 19 X 2us + 20 X 2us = 9954us

5. delay_10ms()程序结束后往下是 子程序返回指令RET,该指令功能是返回到子程序调用指令下一指令处,即返回进delay_ms()前的地方。该指令消耗24个时钟周期,故 t4 = 2us。

综上:可得delay_10ms()执行时间,t = t1 + t2 + t3 + t4 = 2 + 2 + 9954 + 2 = 10000us = 10ms。

验证:分别在进delay_10ms() 和 执行完delay_10ms()后设置断点调试,如图3,可得时间 :

t = 0.01040800sec - 0.00040800sec = 0.01000000sec,即10ms。

 图3

(第一次写文章,写的不好请多多谅解哈)

  • 10
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值