【问题标题】:How does Delay work in PIC ASM? I'm truly baffled延迟在 PIC ASM 中如何工作?我真的很困惑
【发布时间】:2011-02-12 01:34:45
【问题描述】:

我真的完全不明白。我在 cmets 中以某种方式在网上看到的所有代码都有随机数,说明它为什么要执行这么多循环,但实际上并没有解释为什么什么在做什么或在哪里做什么。我真的不知道。

例如:

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

任何帮助都会很棒。

【问题讨论】:

  • 这个汇编代码到底是用于哪个 CPU 的?
  • 16F690 我想回答了你的问题
  • 您的示例不完整(它从不使用Delay3),我不知道您为什么认为它会循环回&amp;&amp;&amp;&amp;。你是怎么想到的?

标签: assembly pic


【解决方案1】:

“我真的完全不明白。我在 cmets 中以某种方式在网上看到的所有代码都有随机数,说明它为什么要执行这么多循环,但实际上并没有解释为什么什么做什么或在哪里做什么谁做的。我真的不知道。”

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

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

16F690 数据表上说:

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

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

最佳 decfsz 延迟 1,f 转到顶部

每次执行 decfsz 时,我们都会获得一个周期的库存。如果 f 为零并且我们必须跳过,那么它就变成了一个两周期指令。每次我们执行 goto 时,pc 都会发生变化,因此它是一个 2 周期指令。所以如果我们走循环,我用格式展示这个

指令前的延迟1值、指令、用于执行的周期、总周期

3,decfsz,1,1 2,转到,2,3 2,decfsz,1,4 1,转到,2,6 1,decfsz,2,8

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

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

如果我们在 Delay1 设置为 11 的情况下进入此循环,则为 ((11-1)*3)+2=32 个周期,7 为 20 个周期。

如果您进一步将一个 decfsz 循环包裹在另一个循环上,您将继续乘以执行的循环数。如果Delay1 是一个3 进入并且Delay2 是一个2

最佳 decfsz 延迟 1,f 转到顶部 decfsz 延迟2,f 转到顶部

那么第一次通过Delay1 decfsz,goto循环我们知道是8个周期。第一个 decfsz Delay2,f 因为 Delay2 不是 1 是 1 的循环,所以我们总共最多 9 个。 goto 还有 2 个,总共 11 个。假设 f 内存是 8 位,那么我们第二次进入延迟 1 循环时,我们输入 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)+((Delay2-1)*3)+2 个周期。

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

入口 movlw .3 movwf 延迟1 movl2 .2 movwf 延迟2 最佳 decfsz 延迟 1,f 转到顶部 decfsz 延迟2,f 转到顶部

我们需要为两个 movlw's 和两个 movwf's 添加 4 个以上的循环到要执行的循环数的整体方程中。

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

让我们更进一步。让我们获取 patrickmdnet 链接的代码生成器以生成 780 个周期:

;延迟 = 780 个指令周期 ;时钟频率 = 4 MHz ;实际延迟 = 0.00078 秒 = 780 个周期 ;误差 = 0 % 块 d1 d2 结束 ;778 个循环 movlw 0x9B movwf d1 movlw 0x01 movwf d2 延迟_0 decfsz d1, f 转到 $+2 decfsz d2, f 转到延迟_0 ;2 个周期 转到 $+1

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

我们从加载 f 寄存器的 4 个周期开始,然后到达 Delay_0

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

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

我们还需要两个周期才能达到 780,这是通过 goto $+1 完成的,goto 修改 pc 使其始终为 2 个周期。我们有我要求程序生成的 780 个周期。

【讨论】:

    【解决方案2】:

    延迟循环背后的想法是燃烧与特定时间量相关的特定数量的循环。每个周期的时间量取决于 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 和 goto 工作原理的更多帮助。

    【讨论】:

    • 我明白,但我喜欢,不知道你从哪里得到确切的时间。你是怎么计算的?这些数字是从哪里来的。如果我将 VAR1 设置为 15,会发生什么,会发生什么变化。如果我将三个延迟变量设置为 4、16、12,那么计时从何而来?这些数字会发生什么导致循环达到特定时间?谢谢
    • 阅读piclist.com/techref/microchip/PIC16DelayTutorial.htm 的底部,详细了解循环计数如何导致秒数。对于单个延迟循环,计算每轮将使用多少个周期,乘以周期 * 计数器,然后将其乘以每个周期的秒数以获得秒数。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-02
      • 2012-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-11
      相关资源
      最近更新 更多