1. 实验背景与目标解析
2017-2018学年第一学期的嵌入式系统课程中,我们小组(学号20155301与2015539)完成了固件程序设计实验。这个实验是嵌入式开发入门的关键环节,主要目标是掌握基于STM32系列微控制器的固件开发全流程。
固件(Firmware)作为硬件与软件的桥梁,在物联网设备、智能硬件等领域应用广泛。通过本实验,我们重点突破了以下三个技术点:
- 寄存器级硬件操作
- 中断服务程序编写
- 外设驱动开发
2. 实验环境搭建
2.1 硬件准备
我们选用STM32F103C8T6最小系统板作为开发平台,其核心参数如下:
| 参数项 | 规格说明 |
|---|---|
| CPU核心 | ARM Cortex-M3 |
| 主频 | 72MHz |
| Flash容量 | 64KB |
| SRAM容量 | 20KB |
| 外设接口 | USART/SPI/I2C/GPIO等 |
2.2 软件工具链
开发环境配置步骤如下:
- 安装Keil MDK-ARM 5.25开发环境
- 下载STM32标准外设库(StdPeriph_Lib V3.5)
- 配置J-Link仿真器驱动
- 新建工程模板并导入库文件
注意:库文件路径不能包含中文,否则会导致编译异常。我们曾因此浪费两小时排查问题。
3. 核心实验内容实现
3.1 GPIO控制LED流水灯
通过直接操作寄存器实现LED跑马灯效果,关键代码如下:
// 初始化GPIOB时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 配置PB0-PB7为推挽输出 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = 0x00FF; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // 流水灯效果实现 while(1) { for(int i=0; i<8; i++) { GPIO_WriteBit(GPIOB, 1<<i, Bit_SET); Delay_ms(200); GPIO_WriteBit(GPIOB, 1<<i, Bit_RESET); } }3.2 USART串口通信
配置串口1实现PC通信,需要注意:
- 波特率计算:72MHz/(16*468.75)=9600bps
- 中断优先级分组设置
实际调试中发现,若未正确配置NVIC优先级分组,会导致通信异常。正确配置示例如下:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;4. 实验问题与解决方案
4.1 常见问题速查表
| 现象描述 | 可能原因 | 解决方案 |
|---|---|---|
| 程序下载后不运行 | 启动模式配置错误 | 检查BOOT0/BOOT1引脚电平 |
| 串口通信乱码 | 波特率不匹配 | 核对双方波特率设置 |
| 外设无响应 | 未开启对应时钟 | 检查RCC相关寄存器 |
4.2 调试技巧分享
- 利用ST-Link Utility读取芯片内部寄存器状态
- 在HardFault_Handler中设置断点分析异常原因
- 使用逻辑分析仪抓取GPIO波形时序
5. 实验拓展与优化
在基础实验完成后,我们尝试了以下进阶开发:
- 移植FreeRTOS实现多任务调度
- 开发PWM呼吸灯效果
- 集成DHT11温湿度传感器
其中PWM配置的关键参数计算过程:
- 定时器时钟:72MHz
- 分频系数:71(得到1MHz计数频率)
- 自动重装载值:999(产生1kHz PWM波)
- 占空比调节范围:0-999
TIM_OCInitStructure.TIM_Pulse = 500; // 初始50%占空比 TIM_OC1Init(TIM3, &TIM_OCInitStructure);通过本实验,我们深刻体会到嵌入式开发中"寄存器思维"的重要性。建议后来者在学习时:
- 养成查阅Reference Manual的习惯
- 建立完整的调试记录文档
- 从底层寄存器操作开始理解,再过渡到库函数使用