我真的根本不明白。我在评论中以某种方式在网上看到的所有代码都有随机数字,说明为什么它会做很多周期,但实际上没有解释为什么做什么或做什么做谁。我真的不知道。
例如:
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
任何帮助都会很棒。
答案 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振荡器的频率决定了时钟周期,而时钟周期又决定了速度。