首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32F1 GPIO寄存器指示灯不闪烁,一直保持亮起

STM32F1 GPIO寄存器指示灯不闪烁,一直保持亮起
EN

Stack Overflow用户
提问于 2021-09-19 23:07:53
回答 2查看 131关注 0票数 0

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

代码语言:javascript
复制
#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);
    
    
    }
    
}

谢谢

EN

回答 2

Stack Overflow用户

发布于 2021-09-20 09:57:12

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

如果您只是想要延迟,请使用sleep()usleep()。这将在一段时间内“阻塞”控制器,所以你不能在此期间做任何事情,除了你的测试,这将是足够的。如果你想要并发计时,可以使用一些systick回调(或中断)。

票数 0
EN

Stack Overflow用户

发布于 2021-10-23 19:03:56

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

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

这无效:

代码语言:javascript
复制
GPIOA->BSRR |= (1<<5); // Set bit 5
delay(200); // delay some time
GPIOA->BSRR |= (1<<21); // Set bit 21 (not 5)

BSRR是只写的,你不应该从它读取。

代码语言:javascript
复制
GPIOA->BSRR = (1<<5); // Set bit 5
delay(200); // delay some time
GPIOA->BSRR = (1<<21); // Set bit 21 (not 5)

如果你想对延迟使用循环,那就用不同的方式来做:

代码语言:javascript
复制
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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69247698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档