如何在STM32F103C8T6上做裸机LED闪烁? [英] How to do bare-metal LED blink on STM32F103C8T6?

查看:27
本文介绍了如何在STM32F103C8T6上做裸机LED闪烁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始探索 STM32 MCU.我想使 BluePill(具有 STM32F103C8T6 MCU)板上的 LED 闪烁.我怀疑我被什么东西误导了.根据F1系列的参考手册,有3个主要步骤:

I have just started exploring STM32 MCUs. I want to blink the LED on the BluePill(having STM32F103C8T6 MCU) board. I suspect I have been mislead by something. As per the Reference Manual of F1 series, There are 3 main steps:

  • 为 PORT 启用时钟(此处为 PORTC)
  • 配置 CNF/MODE 寄存器
  • 根据需要配置 ODR 寄存器,即引脚上的高/低.

我已经按照手册在 KEIL MDK 中编写了代码,但在加载后,代码没有运行,我按下重置按钮然后 LED 亮起,即使我已将设置更改为 RESET &在 KEIL 中运行.

I have written the code in KEIL MDK as per the manual but after it is loaded, The code do not run, I press the reset button and then LED turns ON, even though I have changed Settings to RESET & RUN in KEIL.

这是代码和参考手册的部分.

Here is the code and The parts of reference manual.

#include<stm32f10x.h>

int main(){
    
    RCC->APB2ENR |= 1<<4; //PORTC is on APB2 bus
    GPIOC->CRH |= (1<<20);
    
    while(1){
        GPIOC->ODR |= 0x00002000;
        for(int i = 0; i < 500000;i++); //dummy delay
        GPIOC->ODR &= ~0x00002000;
        for(int i = 0; i < 500000;i++); // dummy delay

    }

}

参考手册:

当我使用调试模式时,我注意到在执行 RCC->APB2ENR |= (1<<4) 后没有为 PORTC 启用时钟.

When I am using the Debug mode, I noticed one thing that the clock is not enabled for PORTC after execution of RCC->APB2ENR |= (1<<4).

LED 不闪烁.我在整个过程中找不到错误.

The LED does not blink. I am unable to find the error in this whole process.

推荐答案

当您编写一个虚拟延迟循环时,聪明的编译器通常会发现这段代码中没有任何值得发生的事情并优化整个事情.

When you write a dummy delay loop, a smart compiler will usually figure out that there is nothing worthwhile happening in this piece of code and optimize the whole thing away.

如果你想知道这是否发生,最好的方法是查看生成的二进制文件的反汇编.

If you want to know this has happened, the best way is to take a look at the disassembly of the generated binary.

幸运的是,C 提供了 volatile 关键字来解决这类问题.它明确告诉编译器不要优化对使用此限定符声明的变量的内存访问.

Thankfully, C provides the volatile keyword to get around exactly this sort of problem. It tells the compiler explicitly to not optimize memory accesses to variables declared with this qualifier.

此处您可以看到一些示例代码,这些示例代码显示了生成的汇编代码在使用和不使用 volatile 关键字使用优秀的 Godbolt 工具.如果没有 volatile,for 循环将被优化为空,并且不会发生 i 的递增或检查.

Here you can see some sample code that shows the difference between generated assembly code with and without volatile keyword using the excellent godbolt tool. Without volatile, the for loop gets optimized to nothing and no incrementing or checking of i ever happens.

因此循环应该写成:

for(volatile int i = 0; i < 500000; i++); //dummy delay

您可能会在嵌入式系统上遇到此类问题,也可能在其他情况下遇到此类问题,例如当您从多个上下文/线程访问一个变量时.

You may run into this kind of issue on embedded systems also in other instances such as when you have a variable being accessed from multiple contexts/threads.

这篇关于如何在STM32F103C8T6上做裸机LED闪烁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆