Delay AS如何在PIC​​ ASM中工作?我真的很困惑

时间:2011-02-12 01:34:45

标签: assembly pic

我真的根本不明白。我在评论中以某种方式在网上看到的所有代码都有随机数字,说明为什么它会做很多周期,但实际上没有解释为什么做什么或做什么做谁。我真的不知道。

例如:

cblock  
Delay1  
Delay2  
Delay3  
endc  

Start:  

.  
.  
.  

Delay  
movlw .2  
movwf Delay1  ;&&&&
movlw .3  
movwf Delay2  
movlw .4       <------ Important note here. For some reason it loops back to the
movwf Delay3   <------ "&&&&" mark when it reads this piece of code. NO IDEA why

DelayLoop  
decfsz Delay1,f    <----- Explain what this does. Where does it get the time from?
goto   DelayLoop   <----- Thanks
decfsz Delay2,f    <-----
goto   DelayLoop  

end

任何帮助都会很棒。

3 个答案:

答案 0 :(得分:4)

“我真的根本不理解。我在评论中以某种方式在网上看到的所有代码都有随机数字,为什么它会做那么多周期,但实际上没有解释为什么做什么或什么做什么是谁。我真的不知道。“

“我理解,但是我喜欢,不知道你从哪里得到确切的时间。你如何计算它?这些数字来自哪里。如果我将VAR1设置为15,会发生什么,会发生什么变化。我将三个延迟变量设置为4,16,12,时间从何而来?这些数字会导致循环达到一定时间?感谢 - Jimmy Page“

如果我理解你的问题,那么:

16F690数据表说:

一个指令周期由四个振荡器周期组成,振荡器频率为4 MHz,这使得正常的指令执行时间为1μs。除非条件测试为真,否则所有指令都在一个指令周期内执行,或者程序计数器因指令而改变。发生这种情况时,执行需要两个指令周期,第二个周期作为NOP执行。

所以假设Delay1的值为3,我们就有了这个循环:

Top
decfsz Delay1,f
goto Top

每次执行decfsz时,我们都会获得一个周期的库存。如果f为零,我们必须跳过,然后它变成一个双周期指令。每次执行goto时,pc都会更改,因此它是一个2周期指令。因此,如果我们走循环并使用格式

显示

指令,指令,用于执行的周期,总周期之前的Delay1值

3,decfsz,1,1
2,goto,2,3
2,decfsz,1,4
1,goto,2,6
1,decfsz,2,8

因此,如果我们以4mhz运行,那么从3开始的Delay1循环需要8个周期或8us。重要的是首先计算周期,然后调整部件的时钟速率,相同的代码在2mhz运行时可以是16us,在1mhz运行时可以是32us。

因此通过检查我们可以看到,对于不是一个的f值,decfsz + goto对是2 + 1 = 3个周期。有一次我们用值1来命中decfsz它将是2个周期。因此,从Delay1为3开始,将有2个非一个条目值(3,2)。最后一次我们点击decfsz并跳过,总周期((3-1)* 3)+ 2 = 8。添加2个周期。

如果我们已将Delay1设置为11进入此循环,则为((11-1)* 3)+ 2 = 32个循环,7为20个循环。

如果进一步将一个decfsz循环包裹在另一个循环中,则继续乘以执行的循环次数。如果Delay1是3进入而Delay2是2

Top
decfsz Delay1,f
goto Top
decfsz Delay2,f
goto Top

然后第一次通过Delay1 decfsz,我们知道goto循环是8个循环。第一个decfsz Delay2,因为Delay2不是1是1个循环,我们总共达到9个。 goto是2个,总共11个。假设f存储器是8位,那么第二次我们按下Delay1循环时我们输入0,将它想象为0x100或256,数学给出我们((256-1) 3)+ 2 =到目前为止,共有767个周期,共778个周期。 Delay2现在是1,所以这是最终的decfsz Delay2,f因此花费我们2,共780个周期。我们可以想出一个算法来计算接近的东西((Delay2-1)(((256-1)* 3)+2))+(((Delay1)-1) * 3)+2)+((延迟2-1)* 3)+2个周期。

虽然我的循环比你的循环小一个decfsz循环,如果你让我的循环与你的相似,那么它会从其他一些指令开始:

Entry
movlw .3
movwf Delay1
movl2 .2
movwf Delay2

Top
decfsz Delay1,f
goto Top
decfsz Delay2,f
goto Top

我们需要为两个movlw添加4个周期,并将两个movwf添加到要执行的周期数的整个公式中。

因此,从字面上看,有一个解释为什么它执行这么多周期。该解释在该设备的数据表中。

让我们进一步。让我们得到patrickmdnet链接到的代码生成器来生成780个循环:


; Delay = 780 instruction cycles
; Clock frequency = 4 MHz

; Actual delay = 0.00078 seconds = 780 cycles
; Error = 0 %

    cblock
    d1
    d2
    endc

            ;778 cycles
    movlw   0x9B
    movwf   d1
    movlw   0x01
    movwf   d2
Delay_0
    decfsz  d1, f
    goto    $+2
    decfsz  d2, f
    goto    Delay_0

            ;2 cycles
    goto    $+1

这个循环的架构有点不同。

我们在到达Delay_0

之前开始加载f寄存器的4个周期

内部decfsz循环goto不直接分支到Delay_0作为你的问题中的代码和我上面的解释,这个跳过decfsz d2,f。因此,对于通过该循环的非一个循环,decfsz有1个循环,goto $ + 2有2个循环,goto Delay_0有2个循环,每个非一个d1总共有5个循环。并且在d1为1的时候再添加两个。这给了我们((0x9B-1)* 5)+2 = 772个周期加上4个周期,然后我们达到776个周期。

有趣的是,最后的decfsz d1,f命中了decfsz d2,f,d2设置为0x01,这意味着它可以保证跳过。这是2个周期,转到$ + 2与另一个goto $ + 1而不是movlw / movwf来加载d2会做同样的事情。无论如何,这2个循环的单指令使我们总共达到778个循环

我们还需要两个周期才能达到780,并且这里使用goto $ + 1来完成,得到修改电脑因此它们总是2个周期。我们要求程序生成780个循环。

答案 1 :(得分:3)

延迟循环背后的想法是燃烧一定数量的与一定时间相关的循环。每个周期的时间长短取决于PIC CPU的时钟速率。

您发布的是一个类似于此处生成的三阶段延迟循环: http://www.piclist.com/techref/piclist/codegen/delay.htm

第一个指令块用计数器加载三个存储单元。使用上面的程序找到最佳值,以产生您想要的延迟。

第二组指令是实际延迟。 &#34; decfsz VAR,f&#34;将VAR减1;如果VAR为零,则跳过下一条指令。所以在上面的例子中,decfsz将一直运行,直到Delay1为零,然后跳过&#34;转到DelayLoop&#34;并开始&#34; decfsz Delay2,f&#34;。

我建议阅读此页: http://www.mstracey.btinternet.co.uk/pictutorial/progtut4.htm

以及此页面: http://www.piclist.com/techref/microchip/PIC16DelayTutorial.htm

获取有关decfsz和goto如何工作的更多帮助。

答案 2 :(得分:1)

内置RC振荡器的频率决定了时钟周期,而时钟周期又决定了速度。