FEATURED · 精选文章

GPIO输入(STM32标准库学习)

发布时间 / 2026/8/31 20:49:43
来源 / 创域科博编辑部
栏目 / 资讯中心
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的更多应用场景如外部中断、定时器输入捕获等为后续的嵌入式开发打下坚实基础。都看到这了点点赞吧求求你了
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻