STM32F103 GPIO标准外设库四灯流水灯实验报告(任务二·Keil5版)
一、实验目的1. 在实验一HAL库四灯流水灯的基础上掌握使用STM32标准外设库Standard Peripheral LibrarySPL控制GPIO端口实现LED流水灯的方法。2. 掌握在Keil5MDK-ARM中手动建立工程、添加STM32标准外设库文件.c、.h的完整过程。3. 理解软件循环延时实现LED亮灭周期的原理并分析其准确周期。4. 对比标准外设库与HAL库两种开发方式的异同。二、实验器材器材说明STM32F103最小系统板Cortex-M3内核72MHz主频自带PC13板载LEDST-Link下载器程序烧录与调试LED发光二极管 × 3红、绿、蓝各一只外部LED面包板及杜邦线电路连接220Ω限流电阻 × 3保护外部LED和GPIO引脚PC电脑 Keil5MDK-ARM 标准外设库开发环境三、实验原理3.1 标准外设库概述STM32标准外设库SPL是ST官方提供的一套底层固件库将寄存器操作封装成函数例如GPIO_Init()配置引脚、RCC_APB2PeriphClockCmd()使能时钟。相比HAL库标准外设库更贴近寄存器、代码简洁是Keil5下经典的STM32开发方式。3.2 GPIO控制原理标准外设库中引脚配置通过GPIO_InitTypeDef结构体与GPIO_Init()完成电平控制通过GPIO_SetBits()高电平和GPIO_ResetBits()低电平实现。本实验沿用实验一的四个LED及电平逻辑PC13板载LED低电平点亮PC14、PA4、PB1三个外部LED高电平点亮。四、实验步骤一在Keil5中创建工程并添加标准外设库文件1. 下载STM32F10x标准外设库如STM32F10x_StdPeriph_Lib_V3.5.0解压后记录Libraries目录位置其中包含CMSIS与STM32F10x_StdPeriph_Driver两个子目录。2. 启动Keil5μVision点击菜单 Project → New μVision Project选择工程保存路径并命名如LEDflow_SPL保存。3. 在弹窗中选择芯片型号ARM → STMicroelectronics → STM32F1xx → STM32F103 → 选择STM32F103RCT6或C8T6点击OK。4. 系统提示Copy STM32 Startup Code to Project Folder?是否拷贝启动文件“选择是”工程自动添加启动文件startup_stm32f10x_hd.s。5. 在左侧Project窗口右键Target1选择Manage Project Items建立如下分组并添加库文件LEDflow_SPL工程 ├─ User/# main.c、stm32f10x_it.c ├─ StdPeriph_Driver/│ ├─ stm32f10x_gpio.c │ ├─ stm32f10x_rcc.c │ └─ stm32f10x_flash.c ├─ Startup/# startup_stm32f10x_hd.s └─ CMSIS/├─ core_cm3.c └─ system_stm32f10x.c6. 添加头文件路径点击工程按钮 Options for Target或AltF7切换到 C/C 选项卡在 Include Paths 中依次添加CMSIS STM32F10x_StdPeriph_Driver/inc User7. 在 C/C 选项卡的 Define 框填入宏定义USE_STDPERIPH_DRIVER, STM32F10X_HD大容量芯片用HD中容量用MD。8. 配置下载调试器切换到 Debug 选项卡选择 ST-Link Debugger再进入 Flash Download 勾选 Reset and Run便于下载后自动运行。9. 将编写好的main.c放入User分组点击编译F7无误后点击下载F8烧录到开发板。二编写主程序main.c中使用标准外设库函数完成时钟使能、GPIO配置与四灯流水控制代码如下#includestm32f10x.hvoidRCC_Configuration(void);voidGPIO_Configuration(void);voidDelay(__IOuint32_tnCount);intmain(void){RCC_Configuration();GPIO_Configuration();while(1){// 1. PC13板载LED亮其余灭GPIO_ResetBits(GPIOC,GPIO_Pin_13);GPIO_SetBits(GPIOC,GPIO_Pin_14);GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_SetBits(GPIOB,GPIO_Pin_1);Delay(0x00100000);// 2. PC14蓝灯亮其余灭GPIO_SetBits(GPIOC,GPIO_Pin_13);GPIO_SetBits(GPIOC,GPIO_Pin_14);GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_SetBits(GPIOB,GPIO_Pin_1);Delay(0x00100000);// 3. PA4红灯亮其余灭GPIO_SetBits(GPIOC,GPIO_Pin_13);GPIO_ResetBits(GPIOC,GPIO_Pin_14);GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_SetBits(GPIOB,GPIO_Pin_1);Delay(0x00100000);// 4. PB1绿灯亮其余灭GPIO_SetBits(GPIOC,GPIO_Pin_13);GPIO_ResetBits(GPIOC,GPIO_Pin_14);GPIO_ResetBits(GPIOA,GPIO_Pin_4);GPIO_SetBits(GPIOB,GPIO_Pin_1);Delay(0x00100000);}}voidRCC_Configuration(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);}voidGPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_ModeGPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz;GPIO_InitStructure.GPIO_PinGPIO_Pin_13;GPIO_Init(GPIOC,GPIO_InitStructure);GPIO_InitStructure.GPIO_PinGPIO_Pin_14;GPIO_Init(GPIOC,GPIO_InitStructure);GPIO_InitStructure.GPIO_PinGPIO_Pin_4;GPIO_Init(GPIOA,GPIO_InitStructure);GPIO_InitStructure.GPIO_PinGPIO_Pin_1;GPIO_Init(GPIOB,GPIO_InitStructure);// 上电全部熄灭GPIO_SetBits(GPIOC,GPIO_Pin_13);GPIO_ResetBits(GPIOC,GPIO_Pin_14);GPIO_ResetBits(GPIOA,GPIO_Pin_4);GPIO_ResetBits(GPIOB,GPIO_Pin_1);}voidDelay(__IOuint32_tnCount){for(;nCount!0;nCount--);}五、软件循环延时周期分析LED的亮灭周期通过软件空循环Delay()实现voidDelay(__IOuint32_tnCount){for(;nCount!0;nCount--);}该函数的核心是一条空for循环每一轮循环执行的耗时取决于以下三个因素因素说明系统主频本实验为72MHz一个CPU时钟周期约1/72MHz ≈ 13.9ns编译优化等级Keil中默认-O0不优化时循环完整保留优化等级高时可能被优化掉导致延时失效汇编指令数-O0下每轮约34条指令加载、减法、比较、跳转共约4个CPU周期因此在72MHz、Keil默认-O0条件下每一轮循环耗时的近似值为单轮耗时 ≈4×13.9ns ≈55ns由此可估算延时延时 ≈ nCount × 55ns。例如Delay(0x00100000)1048576次约延时57ms要接近1秒nCount应约为18×10^6约0x1100000。结论软件循环延时周期的准确值不是固定常数它依赖主频、编译优化等级和编译器版本只能给出量级估算。若要获得精确、稳定的1秒延时应改用SysTick定时器调用SysTick_Config()或硬件定时器实现。六、实验现象上电后四个LED按照以下顺序循环点亮每一盏灯点亮约0.81秒由Delay()循环次数决定PC13板载LED亮 → PC14蓝灯亮 → PA4红灯亮 → PB1绿灯亮 → 循环。任意时刻只有一个LED点亮实现亮灯依次流动的流水灯效果。使用逻辑分析仪观测DBG_PA0、DBG_PA1、DBG_PA2三个LED引脚得到如图1所示的时序波形三个通道输出周期性方波波形之间存在固定的时序偏移印证了四灯按顺序依次点亮的流水灯时序。七、实验中遇到的问题及解决方法问题原因解决方法编译报错找不到头文件未在Include Paths中添加头文件路径在Options for Target的C/C中配置Include PathsGPIO无效或时钟异常未使能GPIO端口时钟调用RCC_APB2PeriphClockCmd()使能对应端口时钟条件编译报错缺少宏定义在C/C的Define中添加USE_STDPERIPH_DRIVER与STM32F10X_HD延时周期不准空循环延时依赖主频与优化等级改用SysTick或硬件定时器实现精确延时八、实验总结本次实验在实验一的基础上改用STM32标准外设库通过Keil5完成了四灯流水灯实验。通过手动添加标准外设库文件掌握了Keil5工程的建立、分组管理、头文件路径配置与宏定义设置方法理解了标准外设库与HAL库在GPIO配置和电平控制上的差异。同时通过软件循环延时实验认识到空循环延时周期的估算方法及其不精确、依赖编译环境的特性为后续使用定时器实现精确延时的学习打下基础。