2

我有一个配置为以 80MHz 时钟速率运行的 PIC32。作为测试,我尝试用

while(1) {        
    LATFbits.LATF4 = !LATFbits.LATF4;
}

它只是根据范围在 625kHz 切换 DIO。查看伪装的列表

9D000118  8C446160   LW A0, 24928(V0)
9D00011C  30840010   ANDI A0, A0, 16
9D000120  2C840001   SLTIU A0, A0, 1
9D000124  8C436160   LW V1, 24928(V0)
9D000128  7C832104   INS V1, A0, 4, 1
9D00012C  AC436160   SW V1, 24928(V0)
9D000130  0B400046   J 0x9D000118

没有那么多指令。为什么这么慢?

===============

最后通过汇编获得 20MHz(4 条指令)

#include<p32xxx.h>

.text
.set    noreorder
.set    nomacro

.global toggle
.ent    toggle

toggle:

# void toggle(int mask)

# $a0 - mask
# performs toggles in an infinite loop (never returns)

# la $t0, 0xbf886160  # LATF base address 04:clear 08:set 12:inv

la $t0,LATF

loop:
sw  $a0,  4($t0)        # write mask to clear 
sw  $a0,  8($t0)        # write mask to set
j loop
nop

.end toggle
4

3 回答 3

1

您是否尝试过使用 INV 寄存器切换 PORT?

除了 TRIS、PORT 和 LAT 基址寄存器之外,每个端口
模块都与一个 SET、CLR 和 INV 寄存器相关联,这些寄存器提供
原子位操作并允许更快的 I/O 引脚操作。

于 2013-06-06T15:29:19.087 回答
0

这些想法呈现不对称波形,但增加了每秒的转换次数。

当我需要高速采样时,我使用了类似的方法——当然是阅读而不是写作。

连同已经提到的其他想法:

while(1) {        
  LATFbits.LATF4 = 0;
  LATFbits.LATF4 = 1;
}

您还可以减少循环的开销

while(1) {        
  LATFbits.LATF4 = 0;
  LATFbits.LATF4 = 1;
  LATFbits.LATF4 = 0;
  LATFbits.LATF4 = 1;
  LATFbits.LATF4 = 0;
  LATFbits.LATF4 = 1;
  ...
  LATFbits.LATF4 = 0;
  LATFbits.LATF4 = 1;
}

使用 PIC24,我可以在许多 DIO 引脚上配置定时器输出,并让硬件生成信号。我怀疑PIC32也可以做到这一点。

于 2013-06-07T18:04:22.760 回答
0

(ds)PIC 的 C30 编译器有_builtin_btg () 在 F 设备上的一条指令和 -E 设备上的 2 条指令中进行位切换。看看PIC32是否也有。可能它只会让你走到一半,因为就像 E 系列一样,afaik PIC32 不一定是 1 个周期/I/O 指令。

同样使用输出比较之类的模块,您可能能够达到更高的速度,如果模块的外围时钟高于 CPU 可以切换的时钟(例如,由于内存延迟)

于 2013-06-11T13:36:35.417 回答