【发布时间】:2020-04-29 16:42:33
【问题描述】:
我有这个简单的内联汇编代码:
__asm__ volatile (
".equ GPIOA_ODR, 0x4001080C \n\t" //GPIOA base address is 0x40010800 and ODR offset is 0x0C
//turns on PA8
"ldr r1, =(1 << 8) \n\t"
"ldr r2, =#GPIOA_ODR \n\t"
"str r1, [r2] \n\t"
//turn off PA8
"ldr r1, =0 \n\t"
"ldr r2, =#GPIOA_ODR \n\t"
"str r1, [r2] \n\t"
);
PA8 只在 2.4MHz 振荡,我想要 36MHz 的速度。我之前尝试过使用计时器并达到了 36MHz 的速度,但由于一些限制,我想避免使用它们。
我不明白为什么 TIMER1 通道 1 (PA8) 可以配置为 36MHz 的开关速度,但是当我尝试在组装中做同样的事情时,我只能在同一个引脚上达到 2.4MHz 的速度。
我也在使用 PinMode(PA8, OUTPUT); 设置 pin
我已经尝试过此汇编代码的其他变体,但在 PA8 上最高只能达到 2.8MHz。我的问题是:STM32f103C8 上的 GPIO 引脚上的开关速度是否高于 2.4-2.8MHz?
(这是Need Help Manipulating Registers in Inline Assembly (STM32F103 "BluePill")之后的后续问题)
【问题讨论】:
-
一般使用软件会有相当多的开销,如果你想要的只是一个脉冲,你的代码可能会更有效率。所以根据你对上一个问题的编辑,你真的读过那篇文章吗?请注意,stm32f1 和 stm32f4 是不同的芯片,具有不同的性能。如果 stm32f103c8 在 gpio 前面有 dma,那么您可以像作者那样使用它
-
如果您想模仿作者所做的软件实验,那么您需要更好地了解系统,正如您在上一个问题中所指出的那样。但无论如何,您在发布的代码中创建的开销是没有理由的。预先设置带有地址和数据的寄存器,通过使用一系列 str 指令执行一系列开关。从闪存运行它,从内存运行它,在一个循环中运行它,每个循环一对一地运行(四个指令 str、str、subs bnz,所有 16 位拇指而不是拇指 2)。然后尝试使用更多的 strs 对,例如 4、8、16、32
-
检查示波器上的输出,看看它在从 st 上的闪存运行时第一次通过循环时的行为,随着 stm32f103 的使用年限,它是否有闪存缓存?接下来的循环呢?你能看到循环结束时的延迟吗(应该可以)。长时间线性运行无循环等情况如何?输出与系统时钟和外围时钟速度相比如何?
-
如果您使用 ldm 和 str 以便您可以从 ram 读取数据然后将其泵入 gpio 端口会怎样。
-
理解当你切换到一个足够快的芯片来做你想做的事情时(这不是你所拥有的),那么你必须重复所有这些,因为时间可能会改变。
标签: assembly stm32 inline-assembly gpio