我从微控制器开始我的旅程,我正在用STM32F1 (带有STM32F103RB的核心板)。我试着用寄存器学习写东西,看起来我被第一个“任务”卡住了--闪烁的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);
}
}谢谢
发布于 2021-09-20 09:57:12
正如dunajski所说,你确定要延迟函数延迟200ms吗?或者更直接地说:永远不要使用NOPs作为延迟。在某些特定的情况下,这可能会在特定的芯片/系统上工作,但您可以假设它不会延迟任何事情。NOP循环将根据编译器的不同进行优化。即使不是,也会在不同的频率/架构上有不同的运行时。
如果您只是想要延迟,请使用sleep()或usleep()。这将在一段时间内“阻塞”控制器,所以你不能在此期间做任何事情,除了你的测试,这将是足够的。如果你想要并发计时,可以使用一些systick回调(或中断)。
发布于 2021-10-23 19:03:56
启用时钟后,您需要等待此操作在总线上传播。它可以通过使用屏障指令或从寄存器回读来存档。
不要使用幻数。使用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://stackoverflow.com/questions/69247698
复制相似问题