单片机
返回首页

Freescale MC9S08AW60汇编学习笔记(六)

2021-08-13 来源:eefocus

延时,汇编中经常要用到的功能,也就是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


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 用NE555制作定时器

    相关电子头条文章