发布时间:2026/8/31 20:50:06
GPIO输入(STM32标准库学习) 在上一篇《GPIO输出STM32标准库学习笔记》中我们学习了如何通过GPIO引脚输出高低电平从而控制LED、蜂鸣器等外设。然而单片机与外界交互不仅需要“输出”更需要“输入”——读取按键是否按下、判断光敏电阻感知的光线强弱等。本篇笔记将延续STM32标准库的学习路线围绕GPIO输入功能展开从按键和传感器模块的原理讲起结合C语言中宏定义、typedef、结构体、枚举等基础语法并通过按键控制LED、光敏传感器控制蜂鸣器两个实战实例帮助大家系统掌握GPIO输入的开发流程。如果觉得有收获可以为我的文章点点小赞这将激励我创作更好的内容谢谢一、GPIO输入1.1 按键介绍按键常见的输入设备按下导通松手断开按键抖动由于按键内部使用的是机械式弹簧片来进行通断的所以在按下和松手的瞬间会伴随有一连串的抖动1.2 传感器模块简介传感器模块传感器元件光敏电阻/热敏电阻/红外接收管等的电阻会随外界模拟量的变化而变化通过与定值电阻分压即可得到模拟电压输出再通过电压比较器进行二值化即可得到数字电压输出1.3 硬件电路1.4 C语言数据类型1.5 C语言宏定义关键字#define用途用一个字符串代替一个数字便于理解防止出错提取程序中经常出现的参数便于快速修改定义宏定义#defineABC12345引用宏定义int a ABC; //等效于int a 12345;1.6 C语言typedef关键字typedef用途将一个比较长的变量类型名换个名字便于使用定义typedeftypedef unsigned charuint8_t;//记得typedef要加分号引用typedefuint8_ta; //等效于unsigned char a;1.7 C语言结构体关键字struct用途数据打包不同类型变量的集合定义结构体变量struct{char x; int y; float z;} StructName;//记得struct也要加分号因为结构体变量类型较长所以通常用typedef更改变量类型名引用结构体成员StructName.x A;StructName.y 66;StructName.z 1.23;或 pStructName-x A; //pStructName为结构体的地址pStructName-y 66;pStructName-z 1.23;1.8 C语言枚举关键字enum用途定义一个取值受限制的整型变量用于限制变量取值范围宏定义的集合定义枚举变量enum{FALSE 0, TRUE 1} EnumName;因为枚举变量类型较长所以通常用typedef更改变量类型名引用枚举成员EnumName FALSE;EnumName TRUE;1.9 模块化编程在之前的51单片机的学习中我们知道利用模块将代码分地方保存以及使用将主函数代码变得简洁美观注意头文件里面可能需要用到别的头文件的函数1.10 有关GPIO输出的库函数让STM32的GPIO输出需要完成3个步骤第一步使用RCC开启GPIO的时钟第二步 使用GPIO_Init函数初始化GPIO第三步使用输入的函数控制GPIO口。1使用RCC开启GPIO的时钟例如RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);2使用GPIO_Init函数初始化GPIO注意GPIO_Speed是GPIO口的输出速度,在GPIO被设置成输入模式下,这个速度是无效的GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin GPIO_Pin_1 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOB,GPIO_InitStructure);3使用输入的函数控制GPIO口ReadInputDataBit——读取某一引脚返回1位输入的高低电平uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);ReadInputData——读取整个寄存器返回16位输入的高低电平uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);ReadOutputDataBit——返回输出数据寄存器的某一个位所以原则上来说它并不是用来读取端口的输入数据的所以原则上来说它并不是用来读取端口的输入数据的这个函数一般用于输出模式下用来看一下自己输出的是什么uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);1.11 实例一3.4.1 按键控制LED利用GPIO输入函数读取引脚电平我们可以获取按键以及传感器给最小系统板输入的数据于是我们可以完成以下内容将LED和独立按键模块化LED.c↓-----------------------------#include stm32f10x.h // Device header /** 函 数LED初始化 参 数无 返 回 值无 */ void LED_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA,GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2); } /** 函 数LED1开启 参 数无 返 回 值无 */ void LED1_ON(void) { GPIO_ResetBits(GPIOA,GPIO_Pin_1); } /** 函 数LED1关闭 参 数无 返 回 值无 */ void LED1_OFF(void) { GPIO_SetBits(GPIOA,GPIO_Pin_1); } /** 函 数LED1状态翻转 参 数无 返 回 值无 */ void LED1_Turn(void) { if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)0 ) { GPIO_SetBits(GPIOA,GPIO_Pin_1); } else { GPIO_ResetBits(GPIOA,GPIO_Pin_1); } } /** 函 数LED2开启 参 数无 返 回 值无 */ void LED2_ON(void) { GPIO_ResetBits(GPIOA,GPIO_Pin_2); } /** 函 数LED2关闭 参 数无 返 回 值无 */ void LED2_OFF(void) { GPIO_SetBits(GPIOA,GPIO_Pin_2); } /** 函 数LED2状态翻转 参 数无 返 回 值无 */ void LED2_Turn(void) { if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2)0 ) { GPIO_SetBits(GPIOA,GPIO_Pin_2); } else { GPIO_ResetBits(GPIOA,GPIO_Pin_2); } }-----------------------------Key.c↓-----------------------------#include stm32f10x.h // Device header #include Delay.h /** 函 数按键初始化 参 数无 返 回 值无 */ void Key_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启GPIOB的时钟 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;//将PB1和PB11引脚初始化为上拉输入 GPIO_InitStructure.GPIO_Pin GPIO_Pin_1 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB,GPIO_InitStructure); } /** 函 数按键获取键码 参 数无 返 回 值按下按键的键码值范围0~2返回0代表没有按键按下 注意事项此函数是阻塞式操作当按键按住不放时函数会卡住直到按键松手 */ uint8_t Key_GetNum(void) { uint8_t KeyNum 0; if( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)0 ) { Delay_ms(20); while( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)0 ); Delay_ms(20); KeyNum1; } if( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)0 ) { Delay_ms(20); while( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)0 ); Delay_ms(20); KeyNum2; } return KeyNum; }-----------------------------江科大老师给的Delay代码模块Delay.c↓-----------------------------#include stm32f10x.h /** brief 微秒级延时 param xus 延时时长范围0~233015 retval 无 */ void Delay_us(uint32_t xus) { SysTick-LOAD 72 * xus; //设置定时器重装值 SysTick-VAL 0x00; //清空当前计数值 SysTick-CTRL 0x00000005; //设置时钟源为HCLK启动定时器 while(!(SysTick-CTRL 0x00010000)); //等待计数到0 SysTick-CTRL 0x00000004; //关闭定时器 } /** brief 毫秒级延时 param xms 延时时长范围0~4294967295 retval 无 */ void Delay_ms(uint32_t xms) { while(xms--) { Delay_us(1000); } } /** brief 秒级延时 param xs 延时时长范围0~4294967295 retval 无 */ void Delay_s(uint32_t xs) { while(xs--) { Delay_ms(1000); } }-----------------------------以下是按键控制LED的主函数代码main.c↓-----------------------------#include stm32f10x.h // Device header #include Delay.h #include LED.h #include Key.h uint8_t KeyNum; int main(void) { LED_Init(); Key_Init(); while(1) { KeyNum Key_GetNum(); if(KeyNum1) { LED1_Turn(); } if(KeyNum2) { LED2_Turn(); } } }-----------------------------1.12 实例二3.5.1 光敏传感器控制蜂鸣器有源蜂鸣器的使用可以说是和LED一模一样以下是有源蜂鸣器的代码模块Buzzer.c↓-----------------------------#include stm32f10x.h // Device header /** 函 数蜂鸣器初始化 参 数无 返 回 值无 */ void Buzzer_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB,GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_12); } /** 函 数蜂鸣器开启 参 数无 返 回 值无 */ void Buzzer_ON(void) { GPIO_ResetBits(GPIOB,GPIO_Pin_12); } /** 函 数蜂鸣器关闭 参 数无 返 回 值无 */ void Buzzer_OFF(void) { GPIO_SetBits(GPIOB,GPIO_Pin_12); } /** 函 数蜂鸣器状态翻转 参 数无 返 回 值无 */ void Buzzer_Turn(void) { if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_12)0 ) { GPIO_SetBits(GPIOB,GPIO_Pin_12); } else { GPIO_ResetBits(GPIOB,GPIO_Pin_12); } }-----------------------------光敏电阻的灵敏度可以通过调节光敏电阻模块的电位器进行修改以下是光敏电阻的代码模块LightSensor.c↓-----------------------------#include stm32f10x.h // Device header /** 函 数光敏传感器初始化 参 数无 返 回 值无 */ void LightSensor_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启GPIOB的时钟 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;//将PB1和PB11引脚初始化为上拉输入 GPIO_InitStructure.GPIO_Pin GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB,GPIO_InitStructure); } /** 函 数获取当前光敏传感器输出的高低电平 参 数无 返 回 值光敏传感器输出的高低电平范围0/1 */ uint8_t LightSensor_Get(void)//暗光返回1 { return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13);//返回PB13输入寄存器的状态 }-----------------------------以下是光敏传感器控制蜂鸣器的主函数代码main.c↓-----------------------------#include stm32f10x.h // Device header #include Delay.h #include Buzzer.h #include LightSensor.h int main(void) { Buzzer_Init(); LightSensor_Init(); while(1) { if(LightSensor_Get()1)//暗光时等于1 { Buzzer_ON(); } else { Buzzer_OFF(); } } }-----------------------------二、总结本文围绕STM32的GPIO输入功能展开系统梳理了从基础概念到实际应用的完整流程。首先介绍了按键和传感器模块的工作原理明确了输入设备如何将外部物理量转化为单片机可识别的数字电平信号随后讲解了硬件电路的基本连接方式为后续编程打下基础。在C语言基础方面本文重点介绍了宏定义、typedef、结构体和枚举等常用语法这些内容在STM32标准库中应用广泛掌握它们有助于理解库函数的定义和使用方式。同时模块化编程的思想贯穿始终通过将LED、按键、蜂鸣器、光敏传感器等功能封装为独立模块使主函数代码更加简洁、可读性更强。在GPIO库函数的使用上本文归纳了三个关键步骤使用RCC开启GPIO时钟、使用GPIO_Init函数初始化引脚、使用输入函数读取引脚电平。通过两个实战实例——按键控制LED和光敏传感器控制蜂鸣器完整演示了GPIO输入功能从初始化到实际应用的开发流程帮助读者将理论知识转化为动手实践能力。总的来说GPIO输入是STM32开发中最基础也最重要的功能之一。掌握本文所讲的内容后读者可以进一步学习GPIO的更多应用场景如外部中断、定时器输入捕获等为后续的嵌入式开发打下坚实基础。都看到这了点点赞吧求求你了

相关新闻

2026/8/31 20:50:06

三极管放大电路为何必须使用直流偏置?原理与工程实践

研究三极管放大电路时,最让人困惑的不是三极管如何把信号变大,而是为什么一套完整的放大电路必须同时存在直流供电和偏置电路。很多人可以背出“基极电流控制集电极电流”这句话,也记住了放大倍数β,但真到搭电路时却会连续问出三…

2026/8/31 20:45:05

1-1 心跳灯 (GPIO输出基础)

1.1 学习目标掌握使用 STM32CubeMX 配置 GPIO 输出的方法熟悉 Keil MDK 工程的编译、下载及基本调试流程实现 LED 周期性闪烁,用于系统运行状态指示1.2 项目原理与概述心跳灯是嵌入式系统中常用的调试与状态指示手段。通过让 LED 以固定频率(如 1Hz&…

2026/8/31 21:05:31

OpenRouter接入Qwen3.8 Flash:统一API调用与本地部署实践

最近在接大模型 API 时,最影响开发效率的往往不是模型效果,而是分散在各平台上的账号、Key 和计费方式。OpenRouter 这类聚合平台出现后,一个 Key 就能访问多个主流模型,模型上新速度也很快。通义千问 Qwen3.8 Flash 上线 OpenRou…

2026/8/31 21:05:31

Python虚拟环境与Jupyter内核配置:NLP关键词提取实战

你是否遇到过这种情况:跟着教程安装了一堆 Python 库,结果某个库版本冲突,程序在本地跑得好好的,到了同事电脑上直接报错;今天要用 TensorFlow,明天要跑一个老项目,可项目用的还是 Python 3.6&a…

2026/8/31 21:05:31

容器镜像CVE治理实战:如何消除上千个漏洞

如果把一个业务镜像拿去做一次完整的漏洞扫描,得到一份包含上千个 CVE 的报告,你会怎么处理?很多团队的第一反应是升级基础镜像、升级依赖、重新构建,然后再次扫描。但下一个季度再扫,报告里又会出现一批新漏洞。这种“…

2026/8/31 21:05:31

数据分析环境创建实战:conda、NumPy与Jupyter搭建指南

1. 为什么数据分析第一步是“环境创建”数据分析入门时,最容易卡住的往往不是算法,也不是数学,而是“环境”两个字。很多初学者会遇到这样的场景:代码在别人电脑上运行得好好的,自己手动敲一遍却报ModuleNotFoundError…

2026/8/31 21:05:31

销售与市场互相甩锅,公司发展战略怎么定

销售与市场互相甩锅,公司发展战略怎么定销售部门抱怨市场部提供的线索数量不足、质量参差不齐;市场部门则指出销售团队对已分配线索跟进不及时、反馈缺失,导致营销投入难以转化为可衡量的签约成果。这种相互指责在To B企业中相当普遍&#xf…

2026/8/31 21:00:31

五原县牙科诊所大揭秘:哪家更值得信赖?

引言在五原县,选择一家值得信赖的牙科诊所对于维护口腔健康至关重要。面对众多牙科诊所,患者常常感到困惑,不知道如何选择。本文将从多个角度分析五原县的牙科诊所现状,并重点介绍五原县苗增泰口腔门诊部的优势,帮助大…

2026/8/31 1:05:20

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/31 2:14:20

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/31 1:41:28

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/8/31 0:07:32

STM32C5设备支持包(IAR DFP)安装指南与常见坑

上一阵子在IAR里折腾一块基于STM32C5系列的新板子,工程从STM32CubeMX导出来之后怎么都编译不过。报错信息很干脆:找不到设备描述文件。跟着错误路径去查,发现指向的是一个让我愣了一下的名字:STMicroelectronics.stm32c5xx.2.1.0.…

2026/8/31 0:07:32

STM32N657 SWO引脚矛盾:CubeMX显示PB3,数据手册为PB5

拿到STM32N657这颗料的第一天,我就撞上了一个让人原地懵圈的引脚矛盾:CubeMX里清清楚楚显示SWO在PB3,翻开数据手册的引脚说明表,却赫然写着PB5。对于一个靠SWO输出调试日志吃饭的人而言,这种"工具和手册打架"…

2026/8/31 12:44:45

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/31 9:19:59

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/31 6:53:02

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…