assembly - STM32f103c8 gpio限速

标签 assembly stm32 inline-assembly gpio

我有这个简单的内联汇编代码:

__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 channel 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") 之后的后续问题)

最佳答案

STM32F103C8 以 72 MHz 的最大时钟速度运行。因此 36 MHz 是可以在 GPIO 上生成的最大频率,因为需要一个单独的时钟周期来设置和清除引脚。这个频率只能通过定时器来实现。
如果你用代码尝试同样的方法,你至少需要三个指令:两个商店和一个分支。这些指令需要大约 6 个时钟周期才能执行,因此最大频率约为 12 Mhz。
为了在软件中实现这一点,您的代码应如下所示:

while (1) {
    GPIOA->ODR = 1 << 8;
    GPIOA->ODR = 0;
}
不需要汇编代码,因为编译器会提供最佳代码。它看起来像这样:
        ldr     r3, .L3
        movs    r1, #128
        movs    r2, #0
.L2:
        str     r1, [r3]
        str     r2, [r3]
        b       .L2
.L3:
        .word   1207959572
更新
我已经在真实世界的设备上对其进行了测试,频率为 8 MHz。我估计这三个指令需要 6 个时钟周期,但似乎需要 9 个周期。
生成的代码或多或少符合预期:
7a:   60d9            str     r1, [r3, #12]
7c:   60da            str     r2, [r3, #12]
7e:   e7fc            b.n     7a <main+0x7a>
范围清楚地显示所有三个指令花费相同的时间。

关于assembly - STM32f103c8 gpio限速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59708656/

相关文章:

gcc - 无效 'asm' : nested assembly dialect alternatives

更正 sys_uname 的内联汇编代码

ARM Cortex-a9 事件计数器返回 0

linux - 使用 's-proc -e' 在 Linux (Fedora) hello.S 上执行汇编 shellcode 返回 SIGSEGV

从 NASM 调用 C 函数 _printf 导致段错误

assembly - 为什么前向引用 ADR 指令在 Thumb 代码中以偶数偏移进行汇编?

c - 使用 CubeMx 通过 USART 传输多个字符串

c - IAR 嵌入式工作台 : Unknown or ambiguous symbol

c - 为什么我在STM32编程中需要死循环?

c - 将CPU和内存管理模型整合在一起