STM32F1 GPIO寄存器LED不闪烁,一直保持

Posted

技术标签:

【中文标题】STM32F1 GPIO寄存器LED不闪烁,一直保持【英文标题】:STM32F1 GPIO registers LED not blinking, just staying on whole time 【发布时间】:2021-11-13 18:21:08 【问题描述】:

我从微控制器开始我的旅程,我正在使用 STM32F1(带有 STM32F103RB 的 Nucleo 板)开始我的旅程。我尝试使用寄存器学习写作,看起来我被第一个“任务”困住了 - 闪烁的 LED。我设法打开了led,但我不能让它闪烁。奇怪的是,当我去调试(我在 Keil uVision 上工作)并查看 GPIOA 外围设备时,端口 5(led 是 PA5)有这个滴答声,这意味着它应该在现实中闪烁。但不是。我尝试更改延迟,但没有任何反应。我被困住了。 我究竟做错了什么? 这是我的代码:

#include "stm32f10x.h"
void delay(unsigned int ms)
    unsigned int i, j;
        for(i = 0; i < ms; i++)
            for(j = 0; j < 20000; j++);

int main(void)
  RCC->APB2ENR |= (1<<2);
    
  GPIOA->CRL |= (   (1<<21));
  GPIOA->CRL &= ~(  (1<<22) | (1<<23) | (1<<20) );
    
  while(1)
  GPIOA->BSRR |= (1<<5);
  delay(200);
  GPIOA->BSRR |= (1<<21);
  delay(200);
    
    
    
    

谢谢

【问题讨论】:

嗨!你确定你的delay 函数会持续 200 毫秒吗? 还要注意BSRR 寄存器是只写的。因此按位 or 操作具有未定义的行为。只需使用GPIOA-&gt;BSRR = (1&lt;&lt;5) 您可以通过使用 Keil 单步执行代码来检查 GPIOA->BSRR 命令。这将消除其他人提到的延迟函数可能出现的错误行为。 【参考方案1】:

正如 dunajski 所说,您确定将函数延迟延迟 200 毫秒吗?或者更直接地说:永远不要使用 NOP 作为延迟。这可能在特定芯片/系统上的某些特定情况下有效,但您可以假设它不会延迟任何事情。 NOP 循环将根据编译器进行优化。即使不是,在不同的频率/架构上也会有不同的运行时间。

如果您只想延迟,请改用sleep()usleep()。这将暂时“阻止”控制器,因此您在此期间不能做任何事情,但对于您的测试,这就足够了。如果您想要并发计时,请使用一些 systick 回调(或中断)。

【讨论】:

【参考方案2】:

启用时钟后,您需要等待此操作通过总线传播。它可以通过使用屏障指令或从寄存器回读来归档。

不要使用幻数。使用来自 CMSIS 的定义。检查是否设置了正确的模式。

这是无效的:

GPIOA->BSRR |= (1<<5); // Set bit 5
delay(200); // delay some time
GPIOA->BSRR |= (1<<21); // Set bit 21 (not 5)

BSRR 只写,您不应该从中读取。

GPIOA->BSRR = (1<<5); // Set bit 5
delay(200); // delay some time
GPIOA->BSRR = (1<<21); // Set bit 21 (not 5)

如果您想使用循环来延迟,请采用不同的方式:

void delay(unsigned int ms)

    unsigned int i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 20000; j++)
            asm(":::memory");

https://godbolt.org/z/6c8dqKT8P

如果您启用优化,您的函数将被优化为单次返回。

https://godbolt.org/z/szfT7Tfv9

【讨论】:

以上是关于STM32F1 GPIO寄存器LED不闪烁,一直保持的主要内容,如果未能解决你的问题,请参考以下文章

STM32使用TIM闪烁LED——输出比较方式

嵌入式STM32F1学习-驱动led灯(寄存器版本)

stm32f042f6p6点亮第一个LED灯

stm32f042f6p6点亮第一个LED灯

stm32端口复用与重映射

stm32f103c8t6 usart1不工作