流水灯控制实验
实验1 流水灯控制实验一、实验目的掌握STM32 GPIO寄存器底层原理理解GPIO端口寄存器地址、配置参数。掌握寄存器方式编写GPIO输出驱动实现LED流水灯。学会STM32标准外设库工程建立、库文件添加方法标准库方式驱动LED。掌握HAL库外部中断实现按键控制流水灯暂停/继续。学会Keil软件仿真逻辑分析仪观测GPIO输出波形测量闪烁周期。二、实验环境硬件STM32F103C8T6最小系统板、3只红绿蓝LED、杜邦线、面包板软件Keil MDK5STM32标准外设库V3.5STM32CubeMXHAL库ST-Link下载器三、实验原理STM32F103的GPIO端口可配置为通用推挽输出模式输出高低电平控制LED亮灭。LED一端串联电阻接GPIO引脚另一端接GNDGPIO输出低电平LED点亮输出高电平LED熄灭。最小系统自带PC13LED原理一致PC13为推挽输出控制板载LED。GPIO关键寄存器以GPIOC为例GPIOC_CRL端口低8位配置寄存器引脚0~7GPIOC_CRH端口高8位配置寄存器引脚8~15PC13在此寄存器GPIOC_ODR端口输出数据寄存器置1输出高电平置0输出低电平RCC_APB2ENRAPB2外设时钟使能寄存器开启GPIO端口时钟任务1寄存器方式实现流水灯包含PC13板载LED1.1 程序设计思路开启GPIOA、GPIOB、GPIOC的APB2外设时钟。配置GPIOA、GPIOB、GPIOC对应LED引脚为推挽输出模式最大速度50MHz。循环依次点亮单个LED其余熄灭软件延时1s不断轮换实现流水灯。将板载PC13 LED加入流水灯序列与外接3个LED轮流闪烁。寄存器地址RCC基地址0x40021000RCC_APB2ENR偏移0x18GPIOA基地址0x40010800GPIOB基地址0x40010C00GPIOC基地址0x40011000寄存器偏移CRL0x00CRH0x04ODR0x0C1.2 寄存器版C代码带详细注释#includestm32f10x.h// 简单软件延时函数粗略延时1svoidDelay_s(uint32_ts){uint32_ti,j;for(i0;is;i)for(j0;j7200000;j);}voidLED_GPIO_Init(void){// 1.开启GPIOA/GPIOB/GPIOC时钟 RCC_APB2ENR*(volatileuint32_t*)(0x400210000x18)|(12)|(13)|(14);// bit2:GPIOA, bit3:GPIOB, bit4:GPIOC// PA0推挽输出 50MHzCRL寄存器*(volatileuint32_t*)(0x400108000x00)~(0x0F0);//清空PA0*(volatileuint32_t*)(0x400108000x00)|(0x030);//0011 推挽输出50M// PB0推挽输出 50MHz*(volatileuint32_t*)(0x40010C000x00)~(0x0F0);*(volatileuint32_t*)(0x40010C000x00)|(0x030);// PC13推挽输出 50MHzCRH寄存器(PC13对应bit20~23)*(volatileuint32_t*)(0x400110000x04)~(0x0F20);*(volatileuint32_t*)(0x400110000x04)|(0x0320);}intmain(void){LED_GPIO_Init();while(1){// PA0亮其余灭*(volatileuint32_t*)(0x400108000x0C)~(10);*(volatileuint32_t*)(0x40010C000x0C)|(10);*(volatileuint32_t*)(0x400110000x0C)|(113);Delay_s(1);// PB0亮其余灭*(volatileuint32_t*)(0x400108000x0C)|(10);*(volatileuint32_t*)(0x40010C000x0C)~(10);*(volatileuint32_t*)(0x400110000x0C)|(113);Delay_s(1);// PC13板载LED亮其余灭*(volatileuint32_t*)(0x400108000x0C)|(10);*(volatileuint32_t*)(0x40010C000x0C)|(10);*(volatileuint32_t*)(0x400110000x0C)~(113);Delay_s(1);}}任务2标准外设库版本流水灯2.1工程项目创建、添加标准库详细步骤1.打开 Keil MDK5新建Project选择芯片STM32F103C8T6创建工程文件夹命名LED_STDLIB。2.从 STM32F10x_StdPeriph_Lib 库中复制inc头文件文件夹、src源文件文件夹到工程目录。3.Keil 工程中点击Manage Project Items新建StdLib分组添加需要的库.c文件stm32f10x_gpio.c、stm32f10x_rcc.c。4.打开OptionsforTarget → C/C添加头文件路径..\inc添加宏定义STM32F10X_MD,USE_STDPERIPH_DRIVER。5.新建main.c添加用户代码编译工程。2.2标准库代码#includestm32f10x.hvoidDelay_s(uint32_ts){uint32_ti,j;for(i0;is;i)for(j0;j7200000;j);}voidLED_Init(void){GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);//PA0GPIO_InitStruct.GPIO_PinGPIO_Pin_0;GPIO_InitStruct.GPIO_ModeGPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_SpeedGPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStruct);//PB0GPIO_InitStruct.GPIO_PinGPIO_Pin_0;GPIO_Init(GPIOB,GPIO_InitStruct);//PC13GPIO_InitStruct.GPIO_PinGPIO_Pin_13;GPIO_Init(GPIOC,GPIO_InitStruct);}intmain(void){LED_Init();while(1){GPIO_ResetBits(GPIOA,GPIO_Pin_0);GPIO_SetBits(GPIOB,GPIO_Pin_0);GPIO_SetBits(GPIOC,GPIO_Pin_13);Delay_s(1);GPIO_SetBits(GPIOA,GPIO_Pin_0);GPIO_ResetBits(GPIOB,GPIO_Pin_0);GPIO_SetBits(GPIOC,GPIO_Pin_13);Delay_s(1);GPIO_SetBits(GPIOA,GPIO_Pin_0);GPIO_SetBits(GPIOB,GPIO_Pin_0);GPIO_ResetBits(GPIOC,GPIO_Pin_13);Delay_s(1);}}2.3软件延时周期Keil 逻辑分析仪仿真1.软件循环延时特点软件空循环延时不精确会受编译器优化、CPU 时钟影响只是粗略1秒。2.Keil 仿真步骤-开启 DebugUse Simulator进入 Debug 模式。-打开Logic Analyzer添加 GPIOA-ODR、GPIOB-ODR、GPIOC-ODR 信号。-运行仿真观测波形高低电平翻转时刻。3.时序分析 逻辑分析仪可以捕获 GPIO 引脚电平跳变测量高电平持续时间、低电平持续时间。 软件延时的实际周期不等于1s存在误差可根据波形读出真实闪烁周期。 任务3HAL 库外部中断按键控制流水灯暂停/继续#includestm32f1xx_hal.h//全局标志uint8_trun_flag1;//1运行0暂停GPIO_HandleTypeDef hgpio_led;GPIO_HandleTypeDef hgpio_key;voidSystemClock_Config(void);staticvoidMX_GPIO_Init(void);voidEXTI0_IRQHandler(void){HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);}//外部中断回调函数voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){if(GPIO_PinGPIO_PIN_0){run_flag!run_flag;//翻转启停状态}}voidDelay_ms(uint32_tms){HAL_Delay(ms);}intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();while(1){if(run_flag1){HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);Delay_ms(1000);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);Delay_ms(1000);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);Delay_ms(1000);}}}staticvoidMX_GPIO_Init(void){GPIO_InitTypeDef GPIO_InitStruct{0};__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();//LED输出GPIO_InitStruct.PinGPIO_PIN_0;GPIO_InitStruct.ModeGPIO_MODE_OUTPUT_PP;GPIO_InitStruct.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOA,GPIO_InitStruct);HAL_GPIO_Init(GPIOB,GPIO_InitStruct);GPIO_InitStruct.PinGPIO_PIN_13;HAL_GPIO_Init(GPIOC,GPIO_InitStruct);//按键PA0 外部中断下降沿GPIO_InitStruct.PinGPIO_PIN_0;GPIO_InitStruct.ModeGPIO_MODE_IT_FALLING;GPIO_InitStruct.PullGPIO_PULLUP;HAL_GPIO_Init(GPIOA,GPIO_InitStruct);HAL_NVIC_EnableIRQ(EXTI0_IRQn);HAL_NVIC_SetPriority(EXTI0_IRQn,0,0);}voidSystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct{0};RCC_ClkInitTypeDef RCC_ClkInitStruct{0};RCC_OscInitStruct.OscillatorTypeRCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEStateRCC_HSE_ON;RCC_OscInitStruct.HSEPredivValueRCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIStateRCC_HSI_ON;RCC_OscInitStruct.PLL.PLLStateRCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSourceRCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMULRCC_PLL_MUL9;if(HAL_RCC_OscConfig(RCC_OscInitStruct)!HAL_OK){Error_Handler();}RCC_ClkInitStruct.ClockTypeRCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSourceRCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDividerRCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDividerRCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDividerRCC_HCLK_DIV1;if(HAL_RCC_ClockConfig(RCC_ClkInitStruct,FLASH_LATENCY_2)!HAL_OK){Error_Handler();}}voidError_Handler(void){__disable_irq();while(1){}}#ifdefUSE_FULL_ASSERTvoidassert_failed(uint8_t*file,uint32_tline){}#endif/* USE_FULL_ASSERT */四、实验结果与分析1.![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7a02300e52404533994dcad8a9890e63.png)(https://i-blog.csdnimg.cn/direct/37bf46c6098f4511b3471e99dd40caca.png)(https://i-blog.csdnimg.cn/direct/735b791fd29e4e8eb518df89869671cc.png)寄存器版本程序下载后PA0、PB0、PC13 板载 LED 轮流点亮间隔约 1s流水灯正常运行验证寄存器配置正确。2.标准库版本调用库函数初始化 GPIO实现相同流水效果Keil 逻辑分析仪观测 GPIO 波形高低电平翻转对应 LED 亮灭。软件空循环延时存在误差实际周期和理论1s 有偏差。3.HAL 库外部中断版本按下按键流水灯暂停再次按下恢复流水实现启停控制。![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/98269a85014d47be8d803effcdb42527.png)(https://i-blog.csdnimg.cn/direct/564a56fccc6f40e8a25afa308a438ca2.png)(https://i-blog.csdnimg.cn/direct/c852b53fa86140dbb688ca8f973d3657.png)(https://i-blog.csdnimg.cn/direct/ebfb093e04cc4b8891f878bffdef447d.png)五、实验总结5.寄存器方式直接操作内存地址底层可控适合理解 STM32 硬件原理代码简洁但可读性差。6.标准外设库封装底层寄存器开发更快工程搭建需要手动添加库文件。7.HAL 库更抽象结合外部中断可以实现按键事件驱动中断不会阻塞主循环。8.软件延时精度低精确定时推荐使用定时器中断Keil 逻辑分析仪可以无硬件示波器情况下观测 GPIO 输出波形调试 GPIO 时序。

相关新闻

《Linux 网络编程》深入理解 IO 多路复用:select 函数详解与 Echo 服务实战

《Linux 网络编程》深入理解 IO 多路复用:select 函数详解与 Echo 服务实战

🔥小叶-duck:个人主页 ❄️个人专栏:《Data-Structure-Learning》《C入门到进阶&自我学习过程记录》 《Linux系统从入门到实践》《Linux网络从入门到实践》 《Qt 方寸极境》 《MySQL》 ✨未择之路,不须回头 已择之路&#xf…

2026/9/30 7:22:17 阅读更多 →
文档站信息架构设计:让核心事实稳定出现在页面中

文档站信息架构设计:让核心事实稳定出现在页面中

很多文档站在内容不断增加后,会出现一个典型问题:页面数量越来越多,但用户和解析工具却越来越难找到基础信息。原因通常不在于内容太少,而在于内容被分散在导航、弹窗、图片、异步接口和多层跳转中。重要信息没有固定位置&#xf…

2026/9/30 7:22:17 阅读更多 →
手机芯片峰值性能卷到头了,今年的真战场在日常使用区间上

手机芯片峰值性能卷到头了,今年的真战场在日常使用区间上

制程进入2nm之后,旗舰SoC的竞争逻辑也在发生变化。先进制程能够提供更高的性能上限,但如何把这部分红利转化为更宽的高能效区间,才真正考验芯片设计能力。从现有测试结果看,天玑 9600 Pro 并没有只把重心放在极限频率,…

2026/9/30 7:22:17 阅读更多 →

最新新闻

Linux软硬链接本质:inode与路径的底层原理

Linux软硬链接本质:inode与路径的底层原理

1. 为什么软硬链接不是“复制”,而是“指针”——从文件系统底层讲清楚你有没有试过用ln命令创建一个链接,结果发现删掉源文件后,软链接打不开、硬链接还能访问?或者反过来,改了软链接指向的文件,硬链接却毫…

2026/9/30 7:56:32 阅读更多 →
Linux软链接与硬链接的本质区别及实战应用

Linux软链接与硬链接的本质区别及实战应用

1. 为什么软链接和硬链接不是“差不多就行”的替代品?在Linux系统里,软链接(symbolic link)和硬链接(hard link)常被新手统称为“快捷方式”,但这种类比会埋下严重隐患。我刚入行时就吃过亏&…

2026/9/30 7:56:32 阅读更多 →
SAP S/4HANA部署方式选择实战决策指南

SAP S/4HANA部署方式选择实战决策指南

简介:本资源是一份面向SAP系统实施顾问、云架构师及企业数字化转型从业者的S/4HANA云部署方式深度解析文档,聚焦SAP官方当前主流的四种部署模型及其业务定位差异,有效解决企业在上云路径选择中的决策困惑。文档以清晰对比方式展开&#xff1a…

2026/9/30 7:56:32 阅读更多 →
uni-app 登录页 UI 精修:从背景层到页面栈的细节实战

uni-app 登录页 UI 精修:从背景层到页面栈的细节实战

uni-app 里给微信小程序做登录页面,第一版基本都停留在“能用”的阶段:一个 logo、两个输入框、一个按钮,收工。等产品拿着竞品截图走过来,说一句“这个登录页面 UI 好看,你照着改一下”,很多人才发现自己在…

2026/9/30 7:56:32 阅读更多 →
uni-app微信小程序登录页:Vue3纯CSS高转化UI实战

uni-app微信小程序登录页:Vue3纯CSS高转化UI实战

做小程序登录页这件事,我前后推倒重来过至少七个版本。第一版是照着教程堆出来的深色背景配白色输入框,自认为挺"高级",结果上线一周后后台数据显示登录页跳出率接近四成;第二版换了配色,数据没动&#xff1…

2026/9/30 7:56:32 阅读更多 →
拆开这个环:优化 RAG 通道,解开 SEO 与 GEO 的死循环

拆开这个环:优化 RAG 通道,解开 SEO 与 GEO 的死循环

摘要:GEO 没有标准,它只是 RAG 的引用打分回路。这个回路正在反向磨平人类内容:RLHF 把 AI 磨成平均值,GEO 再让人类照着这个平均值生长,两个平均化首尾相接,咬成死循环。解法不是拒绝 AI,也不是…

2026/9/30 7:55:32 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →