若晶振为12MHZ,试编写一个延时5MS的子程序

若晶振为12MHZ,试编写一个延时5MS的子程序,第1张

D5MS:

MOV R7,#25

MOV R6,#100

DJNZ R6,$

DJNZ R7,$-4

RET

void delay_ms(unsigned int ms )

{

unsigned char i

while(ms--)

for(i=0i<123,i++)//这是1ms的子函数

}

delay_ms(5) // 就是5ms延时了

哥们你想多了吧!

11.059200MHz晶振下,一个机器指令周期 t=((1*12)/11059200) = 1.0850694us,也就是一个空指令也要1.0850694us,所以5us的延时只能是5个空指令周期,并且误差很大,写成延迟函数误差更大。

在程序中直接:

_NOP_()_NOP_()_NOP_()_NOP_()_NOP_()

这就延时了 5*1.0850694us。

至于5ms的话可以使用定时器,但是误差较大:

void delay_5ms(void)

{

TMOD = 0x01

TH0 = 0x12

TL0 = 0x00

TR0 = 1

while(TF0 == 0)

TF0 = 0

TR0 = 0

}

执行该函数时间会略大于5ms,略大于的部分主要是:

1、进入和退出函数的入栈和出栈 *** 作会占用几个机器周期,具体的自己可以算。

2、初始化定时器和停止定时器也需要几到十几个机器周期那样,具体自己调试算一下。

整体来说,这样误差会在0.1%--1%那样,你可以根据情况来适当的缩小TH0和TL0里面的值。

仿照楼主的问题,进行了程序调试,C调用汇编的时间,可以看插图。

实验证明了三个问题。

1. 使用 RETI 是不必要的,使用 RET 并不报错。

2. C调用这个汇编函数的时间,是 (5 + 5 * n)us。(假设机器周期T=1us)。

3. 从仿真调试过程中,没有看到楼主所说“衰减”的现象。

分析说明如下:

主函数传值到R7:1us;

主函数调用汇编:2us;

汇编返回值(无):0us;

汇编返回(RET):2us;

以上就是公式中的“5us”。

汇编函数体各指令的耗时:

ROND:NOP      1us

MOV 70H,#00H   2us

DJNZ R7,ROND   2us

执行一遍共5us,以R7的值,控制循环次数,故有“5*n(us)”。

条件所限,没有使用示波器进行测试,等以后找个机会吧。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11189137.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-14
下一篇2023-05-14

发表评论

登录后才能评论

评论列表(0条)

    保存