gpt4 book ai didi

assembly - 写一个延迟子程序?

转载 作者:行者123 更新时间:2023-12-02 01:20:34 24 4
gpt4 key购买 nike

我需要编写一个延迟子例程。它应该延迟大约 1 秒。它必须适用于 8051 环境、DS89C430 微 Controller (11.0592 MHz XTAL)。我该如何编写这个子程序?

Delay1sec: ...
....
...
....
...

最佳答案

要获得在中断期间也有效的精确 1 秒延迟,您需要使用硬件定时器,而不是软件定时器。我建议您使用可用的板载计时器 as suggested by Jerry Coffin 之一。

这是一种涉及内置计时器和计数计时器溢出的方法。由于运行定时器默认每 12 个时钟周期更新一次以保持与 8051 的兼容性,因此每秒将更新 921,600 次。一点乘法告诉我们,从 0 计数到 46080 需要 50 ms,这也告诉我们,我们可以在 19456 处启动一个 16 位定时器,等待它溢出 ​​20 次来延迟 1 秒* .

代码可能如下所示:

        CLR     T0M          ; set timer 0 to use a divide-by-12 of
; the crystal frequency (default)

MOV R0,TMOD ; set timer 0 to 16-bit mode without
ORL R0,#01h ; affecting the setup of timer 1
MOV TMOD,R0

LCALL Delay1sec ; call the delay subroutine

Delay1sec:
MOV R0,#20d ; set loop count to 20

loop: CLR TR0 ; start each loop with the timer stopped
CLR TF0 ; and the overflow flag clear. setup
MOV TH0,#4Ch ; timer 0 to overflow in 50 ms, start the
MOV TL0,#00h ; timer, wait for overflow, then repeat
SETB TR0 ; until the loop count is exhausted
JNB TF0,$
DJNZ R0,loop
RET

注意:示例中不包括指令执行时间的开销。
* 数学如何分解:
11059200/12 = 921600
0.05 * 921600 = 46080
65536 - 46080 = 19456 = 0x4C00


软件延迟循环浪费处理器时间并受到中断的干扰。话虽这么说,您可以通过硬编码的方式来完成。

一种方法涉及了解每个机器周期的时钟周期数以及执行各种指令所需的机器周期数。根据data sheet,DS89C430通常每个指令字节使用一个机器周期,并且需要一个周期来执行。 Ultra-High-Speed Flash Microcontroller User's Guide 中提供了每条指令的周期数。

由于您的晶体频率为 11.0592 MHz,因此您的例程将需要延迟 11,059,200 个时钟周期。这通常是通过已知长度的嵌套循环来完成的,然后包括任何额外的循环设置以及可能的子例程调用和返回指令*

该函数可能如下所示:

Delay1sec:                   ; <------------------------------+
; LCALL Delay1sec ; 3 cycles |
MOV R2,#42d ; 2 cycles |
MOV R1,#00d ; 2 cycles |
MOV R0,#00d ; 2 cycles |
loop: DJNZ R0,loop ; 4 cycles <-- l1 <- l2 <- l3 Delay1sec
DJNZ R1,loop ; 4 cycles <---------+ | |
DJNZ R2,loop ; 4 cycles <---------------+ |
RET ; 3 cycles <---------------------+

让我们看看数学是如何分解的**:

l1 = 4 * 256 = 1024 个周期
l2 = (1024 + 4) * 256 = 263168 周期
l3 = (263168 + 4) * 42 = 11053224 周期
延迟1秒 = 11072668 + 3 + 2 + 2 + 2 + 3 = 11053236 个周期

11053236 周期 * 1/11059200 秒/周期 = 999.461 毫秒

* 子程序调用和返回指令可以根据需要省略。
** 我使用 Microsoft Excel 来协助进行与确定循环计数器相关的计算。

关于assembly - 写一个延迟子程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5134836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com