以下是针对STM32F103RC实现LED闪烁(PC13引脚)的三种开发方式示例代码,每种方式均保持相同的核心逻辑:
1. 寄存器开发方式(直接操作寄存器)
cpp
#include "stm32f10x.h"
int main(void) {
// 1. 开启GPIOC时钟 (APB2总线)
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
// 2. 配置PC13为推挽输出模式 (50MHz)
GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13); // 清除旧配置
GPIOC->CRH |= GPIO_CRH_MODE13_0; // 输出模式, 50MHz
while(1) {
// 3. 点亮LED (PC13置低电平)
GPIOC->BSRR = GPIO_BSRR_BR13;
// 4. 简单延时
for(volatile uint32_t i = 0; i < 500000; i++);
// 5. 熄灭LED (PC13置高电平)
GPIOC->BSRR = GPIO_BSRR_BS13;
// 6. 延时
for(volatile uint32_t i = 0; i < 500000; i++);
}
}
2. 标准库开发方式(使用STM32F10x Standard Peripheral Library)
cpp
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
int main(void) {
// 1. 初始化结构体
GPIO_InitTypeDef GPIO_InitStruct;
// 2. 开启GPIOC时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
// 3. 配置PC13参数
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_Init(GPIOC, &GPIO_InitStruct);
while(1) {
// 4. 点亮LED
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
// 5. 延时
for(volatile uint32_t i = 0; i < 500000; i++);
// 6. 熄灭LED
GPIO_SetBits(GPIOC, GPIO_Pin_13);
// 7. 延时
for(volatile uint32_t i = 0; i < 500000; i++);
}
}
3. HAL库开发方式(使用STM32Cube HAL库)
cpp
#include "stm32f1xx_hal.h"
void SystemClock_Config(void); // 时钟配置声明 (通常由CubeMX生成)
int main(void) {
HAL_Init(); // 初始化HAL库
SystemClock_Config(); // 配置系统时钟
// 1. 初始化GPIOC
__HAL_RCC_GPIOC_CLK_ENABLE(); // 使能GPIOC时钟
GPIO_InitTypeDef GPIO_InitStruct = {
.Pin = GPIO_PIN_13,
.Mode = GPIO_MODE_OUTPUT_PP, // 推挽输出
.Pull = GPIO_NOPULL,
.Speed = GPIO_SPEED_FREQ_HIGH // 高速模式
};
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
while(1) {
// 2. 翻转LED状态 (HAL自带延时)
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500); // 使用HAL延时500ms
}
}
// 简化的时钟配置 (实际需根据板晶振修改)
void SystemClock_Config(void) {
RCC_OscInitTypeDef osc = {0};
RCC_ClkInitTypeDef clk = {0};
osc.OscillatorType = RCC_OSCILLATORTYPE_HSE;
osc.HSEState = RCC_HSE_ON;
osc.PLL.PLLState = RCC_PLL_ON;
osc.PLL.PLLSource = RCC_PLLSOURCE_HSE;
osc.PLL.PLLMUL = RCC_PLL_MUL9;
HAL_RCC_OscConfig(&osc);
clk.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
clk.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clk.AHBCLKDivider = RCC_SYSCLK_DIV1;
clk.APB1CLKDivider = RCC_HCLK_DIV2;
clk.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_2);
}
关键差异总结:
特性 | 寄存器开发 | 标准库开发 | HAL库开发 |
---|---|---|---|
代码复杂度 | 高(需直接操作寄存器) | 中(封装硬件操作) | 低(高度抽象) |
可移植性 | 低(芯片依赖性强) | 中(同系列芯片可移植) | 高(跨系列兼容) |
开发效率 | 低(需查阅手册) | 中(接口直观) | 高(集成工具链支持) |
资源占用 | 极小(无库开销) | 中等(需链接库文件) | 较大(库文件体积大) |
适用场景 | 极致优化/资源受限项目 | 传统项目维护 | 快速原型开发/复杂外设操作 |