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

查看:77
本文介绍了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寄存器,即引脚上的HIGH/LOW.

我已经按照手册在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.

在这里,您会看到一些示例代码,显示了使用<和不使用<使用出色的Godbolt工具实现code> volatile 关键字.

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.

因此,循环应写为:

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天全站免登陆