初级会员

- 积分
- 109
- 金钱
- 109
- 注册时间
- 2026-1-29
- 在线时间
- 11 小时
|
以下是一个 STM32F030 基于寄存器操作 的 Demo 范例(以 Keil MDK + SPL 库为例),实现通过按键控制 LED 闪烁。代码完全通过直接配置寄存器完成,避免使用 HAL/LL 库。
硬件连接示例
LED: PA9 (假设低电平点亮)
按键: PC13 (上拉输入,按下时接地)
完整代码 (main.c)
#include "stm32f0xx.h"
// 简单的延时函数(非精确)
void delay(volatile uint32_t count) {
while (count--) __NOP();
}
int main(void) {
// ========== 1. 初始化系统时钟 (HSI 8MHz) ==========
RCC->CR |= RCC_CR_HSION; // 开启内部高速时钟 (HSI)
while (!(RCC->CR & RCC_CR_HSIRDY)); // 等待 HSI 就绪
FLASH->ACR = FLASH_ACR_PREDIV; // 预取使能(提高性能)
RCC->CFGR = 0x00000000; // 系统时钟切换为 HSI
// ========== 2. 初始化 GPIO ==========
// 使能 GPIOA 和 GPIOC 时钟
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOCEN;
// 配置 PA9 为推挽输出 (LED)
GPIOA->MODER |= GPIO_MODER_MODER9_0; // 通用输出模式 (01)
GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR9; // 低速
GPIOA->OTYPER &= ~GPIO_OTYPER_OT9; // 推挽输出
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR9; // 无上下拉
// 配置 PC13 为输入 (按键)
GPIOC->MODER &= ~GPIO_MODER_MODER13; // 输入模式 (00)
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR13_0; // 上拉电阻 (01)
// ========== 3. 主循环 ==========
while (1) {
// 检测按键按下 (PC13 为低电平)
if ((GPIOC->IDR & GPIO_IDR_13) == 0) {
GPIOA->ODR |= GPIO_ODR_9; // 灭灯 (高电平)
delay(500000); // 短延时
GPIOA->ODR &= ~GPIO_ODR_9; // 亮灯 (低电平)
delay(500000); // 长延时
} else {
GPIOA->ODR |= GPIO_ODR_9; // 确保默认灭灯
}
}
}
关键寄存器解析
1. 时钟控制 (RCC)
RCC->CR |= RCC_CR_HSION; // 开启 HSI 时钟
while (!(RCC->CR & RCC_CR_HSIRDY)); // 等待稳定
2. GPIO 模式配置
// PA9 设置为输出
GPIOA->MODER |= GPIO_MODER_MODER9_0; // MODER9[1:0] = 01 (通用输出)
GPIOA->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR9; // 低速输出
// PC13 设置为上拉输入
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR13_0; // PUPDR13[1:0] = 01 (上拉)
3. 读取按键状态
if ((GPIOC->IDR & GPIO_IDR_13) == 0) { ... } // 检查 PC13 是否为低电平
工程配置要点
启动文件: 使用 startup_stm32f030xx.s(Keil 自带)。
链接脚本: 根据芯片内存大小调整(通常 STM32F030 有 32KB Flash + 4KB RAM)。
编译选项: 添加 stm32f0xx.h 头文件路径。
扩展功能建议
如果需要定时器中断或串口通信,可参考以下寄存器级配置:
定时器中断示例
// 初始化 TIM2 (1Hz 中断)
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // 使能 TIM2 时钟
TIM2->PSC = 8000 - 1; // 预分频 (8MHz / 8000 = 1kHz)
TIM2->ARR = 1000 - 1; // 自动重载 (1kHz / 1000 = 1Hz)
TIM2->DIER |= TIM_DIER_UIE; // 使能更新中断
NVIC_EnableIRQ(TIM2_IRQn); // 使能 NVIC 中断
TIM2->CR1 |= TIM_CR1_CEN; // 启动定时器
// 中断服务函数
void TIM2_IRQHandler(void) {
if (TIM2->SR & TIM_SR_UIF) {
TIM2->SR &= ~TIM_SR_UIF; // 清除标志
GPIOA->ODR ^= GPIO_ODR_9; // 翻转 LED
}
}
推荐学习资源
STM32F030 参考手册 (RM0091): 详细描述所有寄存器。
CubeMX 生成寄存器代码: 用 CubeMX 初始化外设后,选择 "Register" 模式生成代码,观察寄存器配置逻辑。
GitHub 开源项目: 搜索 STM32F0 register-based examples。
如果需要其他外设(如 ADC/USART)的寄存器级示例,可以告诉我具体需求! |
|