GPIO输入(STM32标准库学习)

发布时间:2026/10/25 7:51:21

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/10/25 6:02:39

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

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

2026/10/25 7:51:29

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

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

2026/10/25 18:24:57

国内AI大模型架构选型与私有化部署实战指南

1. 国内AI大模型赛道的整体格局与选型逻辑2024年这一年,国内AI大模型领域的变化用“月新日异”来形容一点不夸张。从年初各家忙着晒参数、晒榜单,到年中开始拼落地、拼推理成本,再到年底大家集体转向Agent和多模态,整个行业的节奏…

2026/10/25 18:24:57

手写Trie树实现中文分词:MM/RMM/Bi-MM算法详解

简介:本资源是一份面向高校自然语言处理课程学习者与初学者的高分大作业实践方案,聚焦基于词典的中文分词方法原理与Python工程实现,适用于期末大作业、课程设计等教学场景。压缩包共20个文件,含2个核心Python源码(含详…

2026/10/25 18:24:57

AI Agent工程实现的七要素与七个决策点全解析

前两天一位读者给我发了段 AI Agent 的 Demo,很兴奋地说他能让模型自己调用搜索工具、写文件、做表格了。结果我问了一句"你跑过几个任务",他沉默了。换一个任务就崩,中间步骤出错没人发现,模型甚至会无视工具返回自己编…

2026/10/25 18:24:57

AI芯片深度解析:技术路线、选型逻辑与落地实践指南

1. 为什么现在聊AI芯片,时机刚刚好过去两年,我身边做算法的朋友、做硬件的同事、甚至做投资的朋友,几乎每隔几周就会在群里甩出一篇关于AI芯片的新闻。有人焦虑,有人兴奋,也有人一脸茫然地问:“这玩意儿跟我…

2026/10/25 18:19:57

长任务还活着吗:用进展租约区分卡住与依赖变慢

一个任务每秒上报心跳,十分钟没完成任何步骤。另一个任务正在等待供应商生成视频,三分钟没有新输出,却仍在预期时长内。只凭“几秒没动静就重启”,会把这两种情况混在一起。 活着、前进、拥有写权限 我会分别记三件事&#xff1…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑