STM32F103C8 LED 闪烁

STM32F103C8 LED blink

我尝试编写 STM32F103C8 电路。我使用 ST-LINK V2 编程器。在 运行 使用特殊库的代码示例后,我能够看到内置 LED 点亮,但现在我想在不使用这些库的情况下对电路板进行编程,但我不知道为什么看不到任何东西,LED 一直处于关闭状态。 这是代码:

#include "stm32f10x.h"                  // Device header

int main(){
    RCC->APB2ENR |= 1<<4;
    GPIOC->CRH &= ~0xFF0FFFF;
    GPIOC->CRH |= 0x00300000;
    GPIOC->ODR |= 1<<13;//turn PC_13 ON
    while(1){
        
    }
}

根据您在 PC13 上有 LED 的信息,我假设您使用的是著名的 Blue Pill 开发板。在那块板上,由于 PC13 的特殊限制,LED 连接是倒置的——该引脚只能吸收电流,不能提供电流。所以,为了打开它,你需要将0写入ODR的相应位。

通常,我反对使用幻数。但对于 STM32F103,使用十六进制文字进行 GPIO 配置是实用的,因为一个十六进制数字唯一定义了引脚模式。人们可以记住 GPIO 设置的十六进制文字的含义,并将它们用于一次定义 GPIO 端口的 8 个引脚的紧凑分配中。如果您只进行一次 GPIO 配置,则不需要 &=|= 运算符。

此外,更喜欢使用 BSRR 而不是 ODR,因为它允许对输出引脚进行原子修改。

这是 Blue Pill 开发板的 LED 闪烁示例:

//========================================================================
// Includes
//========================================================================
#include "stm32f1xx.h"
#include <stdbool.h>
#include <stdint.h>

//========================================================================
// Local Variables
//========================================================================
volatile uint32_t sysTick = 0;

//========================================================================
// Local Function Prototypes
//========================================================================
void initialize(void);
void delayMs(uint32_t ms);

//========================================================================
// Initialization
//========================================================================
void initialize(void) {

    SystemCoreClock = 8000000U;

    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN // Enable PortC
            | RCC_APB2ENR_AFIOEN; // Enable A.F.Z

    // Pin Remaps
    AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // JTAG is disabled

    // GPIO Settings
    GPIOC->CRH = 0x44244444; // LED connected to PC13
    GPIOC->BSRR = (1 << 13); // LED is inverted, turn it off.

    // SysTick Settings
    SysTick_Config(SystemCoreClock / 1000);

    // Initialization Done Signal
    GPIOC->BSRR = (1 << (13 + 16));
    delayMs(200);
    GPIOC->BSRR = (1 << 13);
}

//========================================================================
// Main
//========================================================================
int main(void) {

    initialize();

    while (true) {
        delayMs(500);
        GPIOC->BSRR = (1 << (13 + 16));
        delayMs(500);
        GPIOC->BSRR = (1 << 13);
    }
}

//========================================================================
// Interrupt Handlers
//========================================================================

void SysTick_Handler(void)
{
    ++sysTick;
}

//========================================================================
// Local Functions
//========================================================================

void delayMs(uint32_t ms) {
    uint32_t start = sysTick;
    while (sysTick - start < ms);
}
#include "stm32f10x.h"                  // Device header

int main(void){
    RCC->APB2ENR |= 1<<4;
    GPIOC->CRH &= 0xFF0FFFF;//clear the necessary bit 
    GPIOC->CRH |= 0x00300000;//set the necessary bit
    GPIOC->ODR &= ~(1<<13);//turn PC_13 ON
        while(1){
        
    }
}

此代码有效。问题是 PC13 控制的是阴极,而不是内置 LED 的阳极。 这就是为什么我应该写:GPIO->ODR &= ~(1 << 13); 以打开 LED。