一、实验目的
- 掌握STM32标准外设库(SPL)的工程搭建与GPIO库函数用法;
- 用标准外设库实现LED轮流闪烁;
- 使用Keil软件仿真逻辑分析仪观察GPIO输出波形,分析闪烁周期。
二、实验硬件
| 元件 | 引脚 | 说明 |
|---|---|---|
| 红色LED | PA0 | 高电平亮 |
| 蓝色LED | PA2 | 高电平亮 |
| 绿色LED | PB0 | 高电平亮 |
| 板载LED | PC13 | 低电平亮 |
三、工程项目创建与添加库文件详细过程
3.1 新建Keil工程
- 打开Keil μVision5 → Project → New μVision Project;
- 选择保存路径,命名为
Task2_SPL; - 器件选择窗口选STMicroelectronics → STM32F1 Series → STM32F103 → STM32F103C8;
- 弹出"Manage Run-Time Environment",先点Cancel,后面手动加库。
3.2 目录结构
在工程文件夹下建立如下结构:
Task2_SPL/ ├── Libraries/ │ ├── inc/ (标准外设库头文件) │ │ ├── stm32f10x.h │ │ ├── stm32f10x_gpio.h │ │ ├── stm32f10x_rcc.h │ │ ├── core_cm3.h │ │ ├── system_stm32f10x.h │ │ └── stm32f10x_conf.h │ └── src/ (标准外设库源文件) │ ├── stm32f10x_gpio.c │ ├── stm32f10x_rcc.c │ ├── system_stm32f10x.c │ └── misc.c ├── Startup/ │ └── startup_stm32f10x_md.s (启动文件) ├── User/ │ └── main.c └── Listings/ Objects/ (编译输出)3.3 添加源文件到Keil
- 在Keil左侧Project面板,右键Source Group 1→ Add Existing Files;
- 选择
Libraries/src/下的:stm32f10x_gpio.cstm32f10x_rcc.csystem_stm32f10x.cmisc.c
- 再把
startup_stm32f10x_md.s和User/main.c加进来。
3.4 配置头文件路径与宏
右键工程 →Options for Target(或按Alt+F7);
切到C/C++选项卡:
Include Paths点…加入:
../Libraries/inc ../UserDefine框中填入:
USE_STDPERIPH_DRIVER, HSE_VALUE=8000000
切到Debug选项卡:
- 选Use Simulator(软件仿真);
- 点Settings→ 仿真选项卡中
Dialog DLL保持默认;
点OK保存。
四、程序代码
#include"stm32f10x.h"/* 软件延时约1ms(8MHz主频粗略值) */voidDelay_ms(volatileunsignedintms){unsignedinti,j;for(i=0;i<ms;i++)for(j=0;j<800U;j++){;}}intmain(void){GPIO_InitTypeDef GPIO_InitStruct;/* 1. 开GPIOA/B/C和AFIO时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);/* 2. PA0、PA2 推挽输出50MHz */GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_2;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);/* 3. PB0 推挽输出50MHz */GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;GPIO_Init(GPIOB,&GPIO_InitStruct);/* 4. PC13 推挽输出50MHz */GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13;GPIO_Init(GPIOC,&GPIO_InitStruct);/* 5. 初始全灭:外接灯写0,板载灯写1 */GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_2);GPIO_ResetBits(GPIOB,GPIO_Pin_0);GPIO_SetBits(GPIOC,GPIO_Pin_13);/* 6. 流水循环 */while(1){/* 红灯 PA0 */GPIO_SetBits(GPIOA,GPIO_Pin_0);Delay_ms(1000);GPIO_ResetBits(GPIOA,GPIO_Pin_0);/* 蓝灯 PA2 */GPIO_SetBits(GPIOA,GPIO_Pin_2);Delay_ms(1000);GPIO_ResetBits(GPIOA,GPIO_Pin_2);/* 绿灯 PB0 */GPIO_SetBits(GPIOB,GPIO_Pin_0);Delay_ms(1000);GPIO_ResetBits(GPIOB,GPIO_Pin_0);/* 板载灯 PC13(低电平亮) */GPIO_ResetBits(GPIOC,GPIO_Pin_13);Delay_ms(1000);GPIO_SetBits(GPIOC,GPIO_Pin_13);}}五、Keil软件仿真逻辑分析仪观察波形
5.1 操作步骤
- 编译通过后按Ctrl+F5进入Debug仿真;
- 菜单View → Analysis Windows → Logic Analyzer;
- 在弹出的Logic Analyzer窗口点Setup(左上角);
- 点New(Insert),依次添加:
PORTA.0(红灯)PORTA.2(蓝灯)PORTB.0(绿灯)
- 每个信号的Display Type改为Bit;
- 点Close,然后按F5运行;
- 波形绘制出来后,用Zoom In/Out调整时间轴。
5.2 仿真波形图
5.3 波形分析
| 信号 | 引脚 | 高电平时间 | 低电平时间 | 周期 |
|---|---|---|---|---|
| 红色 | PA0 | 约1s | 约3s | 约4s |
| 蓝色 | PA2 | 约1s | 约3s | 约4s |
| 绿色 | PB0 | 约1s | 约3s | 约4s |
- 三个引脚均为方波,高电平宽度约1秒,对应每只灯点亮的时间;
- 低电平约3秒,对应其余3只灯轮流亮的时间;
- 三路信号相位依次错开,符合流水灯逻辑;
- 高低电平转换周期(LED闪烁周期)实测约为1秒,与软件延时目标值基本一致;
- 软件循环延时不是精确1秒,受编译器优化和指令周期影响,若需精确周期应改用SysTick定时器。
六、实验总结
通过本实验,掌握了标准外设库的工程搭建方法,学会了用库函数(RCC_APB2PeriphClockCmd、GPIO_Init、GPIO_SetBits等)快速配置GPIO,并使用Keil逻辑分析仪直观观察到了流水灯的输出时序波形,验证了代码逻辑的正确性。