2011-02-12 59 views
1

我真的不明白它。我在评论中以某种方式看到的所有代码都有随机数字,说明它为什么会进行这么多次循环,但是为什么会做什么或在哪里做了什么,实际上没有解释。我真的不知道。延迟如何在PIC​​ ASM中工作?我真的很困惑

例如:

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 

任何帮助将是非常美妙的。

+2

这个汇编代码究竟是哪个CPU? – zwol 2011-02-12 01:54:19

+0

16F690我想回答你的问题 – 2011-02-12 02:38:55

+1

你的例子是不完整的(它从来没有使用`Delay3`),我不知道你为什么认为它循环回到&&&&`。你是怎么想出来的? – Gabe 2011-02-12 03:04:47

回答

3

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

你贴什么类似于这里生成的那些三阶段延迟循环: http://www.piclist.com/techref/piclist/codegen/delay.htm

的指令的第一个块加载设有专柜三个存储位置。使用上面的程序找到最佳值来产生你想要的延迟。

第二组指令是实际的延迟。 “decfsz VAR,f”将VAR减1;如果VAR然后为零,则跳过下一条指令。因此,在上述情况下,decfsz将运行到Delay1为零,然后跳过“goto DelayLoop”并启动“decfsz Delay2,f”。

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

而且此页: http://www.piclist.com/techref/microchip/PIC16DelayTutorial.htm

更多的帮助就转到如何DECFSZ和作品。

4

“我真的完全不明白。我看到网上莫名其妙的评论代码有它为什么这样做,许多周期的随机数,但硬是没有解释为什么什么做什么或在什么是谁,我真的不知道。“

“我明白,但我喜欢,不知道你从哪里得到EXACT时间,你如何计算它?这些数字从哪里来。如果我将VAR1设置为15,会发生什么变化。如果我将三个延迟变量设置为4,16,12,那么时间从何而来?这些数字会导致循环成为特定时间?谢谢 - Jimmy Page“

如果我理解您的问题则:

的16F690数据表表示:

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

因此,可以说延迟1的值是3,我们有这样的循环:

 
Top 
decfsz Delay1,f 
goto Top 

我们每次执行DECFSZ我们时间获取股票一个周期。如果f为零,我们必须跳过,那么它变成了一个两周期的指令。每次我们执行goto时,pc都会改变,所以它是一个2周期的指令。所以,如果我们走循环,我告诉这个使用格式

延迟1值之前的指令,指令,使用周期来执行,总周期

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

使环本身与延迟1开始的3拿了8周期或8us,如果我们在4mhz运行。首先计算周期,然后调整器件的时钟速率非常重要,相同的代码在2mhz运行时可能为16us,而在1mhz运行时可能为32us。

所以通过检查我们可以看出,对于f值不是1的情况,decfsz + goto对是2 + 1 = 3个周期。有一次,我们打到decfsz的值为1,这将是2个周期。因此,从3的Delay1开始,将有2个非一个入口值(3,2)。并且在上次我们击中decfsz并跳过时总共添加2个周期((3-1)* 3)+ 2 = 8。

如果我们已经进入这个Delay1设置为11的循环,它将是((11-1)* 3)+2 = 32个循环,一个7将是20个循环。

如果你继续往下走一个decfsz循环,你会继续乘以执行循环的次数。如果延迟1是一个3进入和延迟2是一个2

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

然后第一次通过延迟1 DECFSZ,转到循环中,我们所知道的是8个周期。第一个decfsz Delay2,因为Delay2不是1是1的周期,我们总共达到了9。 goto是2个,共11个。假设f存储器是8位,那么当我们第二次点击Delay1循环时,我们输入0,把它看作是一个0x100或者256的数学运算给我们((256-1)3)+2 = 767 more到目前为止共有778个周期。 Delay2现在是1,所以这是最终的Decfsz Delay2,f这样花费我们2,总共780个周期。 (((Delay-1)(((256-1)* 3)+2))+(((Delay1)-1)* 3)的周期计算算法, +2)+((Delay2-1)* 3)+2个周期。

虽然我的循环是由一个DECFSZ环比你小的,如果你让我的像你,因为它与其他一些指令开始:

 
Entry 
movlw .3 
movwf Delay1 
movl2 .2 
movwf Delay2 

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

我们需要增加4个周期以上两个MOVLW的以及两个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 

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

我们先从装载在F寄存器的4个周期之前,我们得到Delay_0

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

有趣的是,最后一个decfsz d1,f命中一个decfsz d2,f,并将d2设置为0x01,这意味着它保证跳过。它是2个周期,转到$ + 2与另一个转到$ + 1而不是movlw/movwf加载d2会做同样的事情。反正2个周期的这个单指令给我们带来最多,共778个周期

我们需要两个以上的周期才能到780和与一个goto $ + 1在这里完成,goto方法修改PC所以他们总是2周期。我要求程序生成780个周期。

1

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