assembly - 在 20 MHz(?) 时钟上添加 1 秒延迟

标签 assembly pic

编辑:PIC 16F684

好的,我有一个简单的 3 LED 二进制时钟,从 0 到 7 计数,并且希望在每个灯打开之间添加大约 1 秒的延迟。

我发现每个灯都需要处于某种循环中,并且我必须使用计数来测量滴答声和翻转等。

认为时钟是4MHz,这是手册的屏幕截图:/image/3A3sJ.png

以下是我的代码的相关摘录:

COUNT1 EQU 20h      ; Delay counter #1
COUNT2 EQU 21h      ; Delay counter #2

...

LOOP0
        MOVLW   TRIS_D0_D1      ; Move value defined in Constants to TRISA, to switch on LED 0.
        TRIS    PORTA           ;
        CLRF    PORTA           ; Clear all outputs.
        MOVLW   D0              ; Set the accumulator to the value of D0.
        MOVWF   PORTA           ; Move the accumulator to PORTA, to switch on LED 0.

    ; Using COUNTs to add a delay
        decfsz    COUNT1,1       ; Decrease COUNT1 by 1, and skip the next line if the result is 0.
        goto      LOOP0          ; If COUNT1 is 0, carry on. If not, go to LOOP0.   
        decfsz    COUNT2,1       ; Decrease COUNT2 by 1, and skip the next line if the result is 0.
        goto      LOOP0          ; If COUNT1 is 0, carry on. If not, go to LOOP0.

但是,我相当确定我搞砸了时间,有人可以帮我吗?

最佳答案

假设:LOOP0 处的代码是您希望每次延迟执行一次的代码,而不是在延迟期间执行尽可能多次的代码。我还假设您将 COUNT1COUNT2 设置为某项 - 您发布的代码声明了两个“变量”,但没有分配它们。

您现在的代码将重复执行 LOOP0 COUNT1 + COUNT2 次代码。这是因为每个循环都是独立的。这为您提供了 510 个周期的最大延迟。正如其他评论者所说,PIC16 每个周期大约执行一条指令,因此您需要延迟 1,000,000 个周期才能在 4MHz 下等待一秒钟。

如果我们考虑要等待 196392 周期的情况,我们本质上需要实现一个 16 位计数器。我们通过在循环中递减一个计数器来实现这一点。每次循环退出时,我们都会减少另一个计数器。当两个计数器都为零时,循环返回。这是一个例子:

COUNT1 EQU 20h
COUNT2 EQU 21h

LOOP0
    ;do some stuff here
        ...

    ;delay loop starts here:
    ;assume COUNT1=0 and COUNT2=0
Delay_0
    decfsz COUNT1
    goto Delay_0
    decfsz COUNT2   ;COUNT1 = 0 so 0xff cycles have passed
    goto Delay_0
    goto LOOP0 ;both COUNT1 and COUNT2 = 0 - 196392 cycles have now passed

分支指令如果不跳过则花费 1 个周期,如果跳过则花费 2 个周期。 goto 始终需要 2 个周期,这意味着完成一次完整计数所需的实际时间是 767 个周期 (255 * 3 + 2)。我们可以将两者所花费的时间计算为 ((255 * 3 + 2) + 3) * 255 + 2。

有一个很棒的 explanation of delay routines结束于 Dos4Ever。这将介绍延迟例程如何工作以及如何计算延迟例程的计数器值和成本。

最后,如果您只想剪切和粘贴延迟例程,Delay routine generator在 PIClist 上已经非常完美了。

关于assembly - 在 20 MHz(?) 时钟上添加 1 秒延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10375034/

相关文章:

C++ 在嵌入式系统中需要汇编

c - 如何解决 C 和函数指针中的循环依赖问题

linux - 我想继续学习 µC 编程,但我完全不知道从哪里开始

c - 由于需要结构/union ,microC 构建失败

c - GDB和汇编: how to examine consts variables defined in heap?

c - 跟踪/分析说明

c - 七段显示滚动

c - 使用范围值的 for 循环

c - 使用内联汇编将 int 保存在来自结构指针的函数变量中

c - 在缓冲区溢出返回地址被不正确的地址覆盖,但它仍然有效