历史上的今天
今天是:2025年08月13日(星期三)
2021年08月13日 | 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
史海拾趣
|
看到坛子里很多人拿到板子后不知道第一步该如何做, 在网上看到一个朋友的博客,感觉还不错,对于购买板子的朋友应该有所帮助,所以呈现出来: 来源:http://adreaman.com/0524arm-mini2440-led-key-non-os.html mini2440是当前最经济的arm9开 ...… 查看全部问答> |
|
Keil uv3快速入门 demo https://bbs.eeworld.com.cn/thread-98020-1-1.html… 查看全部问答> |
|
我最近在网上找到这么个简单的基于51单片机的多任务操作系统,但是我不知道其中task-swith和task-load这两个函数是怎么切换任务的,用堆栈管理实现任务的切换,请高手帮我解释下,谢谢 我主要想知道51单片机怎样去识别任务切换 程序 /* ...… 查看全部问答> |
|
系统:s3c2440a +wince5 想在系统运行时,关闭UPLL,不产生48Mhz,在需要时再打开UPLL 查看s3c2440a的datasheet,上写控制CLKSLOW寄存器的UCLK_ON即可 CLKSLOW[7] --> UCLK_ON --> = 0 UCLK_ON (UPLL turn on)   ...… 查看全部问答> |
|
(重分答谢)AT 命令 STATE: IP IND(连线失败,接受场景配置) 我再WinCE5.0上用GPRS上网发信息到服务器上: AT+CREG? // check if registration network in 2 seconds interval +CREG: 0,1 // module responses AT+CGATT? // check if attach PDU for 2 seconds interval +CGATT: 1 // module response ...… 查看全部问答> |
|
我现在手上有一个针对某个设备的 WinCE5.0 SDK包。 如何知道其在原版WinCE上做了哪些裁剪? 相关目录如下: [Atl] [Help] [Include] & ...… 查看全部问答> |
|
如果想在wince中自己开发一个中文输入法,要是用EVC的话,应该如果建立拼音和汉字字库的检索? 有没有相关的API函数? 要是想开发一个手写中文输入软件呢?都需要怎么去开发?… 查看全部问答> |




