Freescale MC9S08AW60汇编学习笔记(六)

  延时,汇编中经常要用到的功能,也就是MCU什么也不做,仅仅是拖延一段时间而已。MCU本身就有定时器、计数器,用来实现延时当然不在话下,但是一个编程的人自然更希望要实现的功能更加易于掌控,我们就用代码、用程序来实现延时,也就是采用软件进行延时。具体做法是:通过A、H:X增减指令、空操作指令nop和brn以及相应的转移指令,再利用循环结构就可以实现延时功能。既然是延时,能知道延时多长时间最好了,我们知道的是:MCU总线时钟频率为4MHz,所以一个总线周期占用的时间为0.25us,这样,只要知道每条指令所占用的总线周期就可以计算我们的程序运行了多久。实现延时自然也是这样,这些当然要用到数学知识了,放心的是还不至于用到微积分,只要耐心一点精确地计算出延时的时间并不是难事。

  例子:设计一个延时10ms的延时子程序,已知MCU总线时钟频率为4MHz。

分析:由于总线时钟频率为4MHz,故一个总线周期占用的时间为0.25us,10ms延时需要执行相当于40000个总线周期的指令。我们可以先设计一个实现较小延时的子程序Re_cycle,然后多次循环调用该子程序来实现较长的时延。代码如下:

 org $0070
num ds.b 1
count1 ds.b 1

 org $1860
re_cycle:                              ;4+7*70+6=500T=125us
  mov #70T,num              ;4T
  dbnz num,*                    ;7T
  rts                                  ;6T
delay_10ms:                        ;[4+78*(5+7+500)]+4+7*7+6=39999T
  mov #78T,count1          ;4T
re_call:
  bsr re_cycle                    ;5T
  dbnz count1,re_call         ;7T
  mov #07T,count1           ;4T
  dbnz count1,*                 ;7T
  rts                                   ;6T

main:
  bsr delay_10ms               ;5~6T
again:
  nop
  jmp again


 org $fffe
 dc.w main

  每一条指令所占用的时间皆已标出,需要的就是精巧的设计和精准的计算,比如Re_cycle子程序的设计三条指令刚好500T,这里要解释一下DBNZ这个指令,它所实现的功能就是前面变量中的数自减1与0比较,不等就转移到后面的地址并执行,相等就结束该指令(也就是减1不为0转移指令)。这里肯定要问*代表什么,它代表的就是它本身所在指令的地址,dbnz num,*   指令就可以解释为num自减1不等于0就回来再执行该语句,知道num自减1等于0后结束。由注释看出,delay_10ms子程序执行完所占用的总时间为39999T,再加上在main主程序中对delay_10ms子程序的调用占用5~6T,这样没调用delay_10ms一次,便可以实现40004~40005个总线周期约10ms的延时。当然,如果设计足够好,还可以更精确,越靠近40000个T越好。

  上面实现了延时10ms,那如果要实现100ms,500ms,1ms,0.1ms呢,同样的办法,全靠精巧的设计和精准的计算。下面给出延时1ms和500ms的子程序:

 org $0070
num ds.b 1
count1 ds.b 1
count2 ds.b 1

 org $1860
re_cycle:                          ;4+7*70+6=500T=125us
  mov #70T,num
  dbnz num,*
  rts

delay_1ms:                      ;[4+(5+7+500)*8+6]=4106T
  mov #08t,count
  re_call:
  bsr re_cycle                
  dbnz count,re_call
  rts

delay_10ms:                    ;39999T
  mov #78T,count1
re_call:
  bsr re_cycle
  dbnz count1,re_call
  mov #07T,count1
  dbnz count1,*
  rts

delay_500ms:                      ;想法是将delay_10ms重复执行50次,这样肯定有不精确的地方,还请见谅。
  mov #50T,count2
re:
  bsr delay_10ms
  dbnz count2,re
  rts


main:

  bsr delay_1ms
  bsr delay_10ms

  bsr delay_500ms
again:
  nop
  jmp again


 org $fffe
 dc.w main

 

转载于:https://www.cnblogs.com/daviddolphin/p/4470524.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值