news 2026/10/23 2:18:43

【stm32 库函数开发】03 GPIO功能

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【stm32 库函数开发】03 GPIO功能

提示:stm32 基于库函数开发,GPIO 相关。

文章目录

    • 1. GPIO 简介
      • 1.1 基本结构
      • 1.2 模式
      • 1.3 寄存器
        • 1.3.1 端口功能配置寄存器
        • 1.3.2 数据输入寄存器
        • 1.3.3 数据输出寄存器
        • 1.3.4 位设置/位清除寄存器
        • 1.3.5 位清除寄存器
      • 1.4 库函数
    • 2. GPIO 输出及应用
      • 2.1 led 灯
        • 2.1.1 基础
        • 2.1.2 硬件电路
        • 2.1.3 软件实现
      • 2.2 蜂鸣器
        • 2.2.1 基础
        • 2.2.2 硬件电路
        • 2.2.3 软件实现
    • 3. GPIO 输入及应用
      • 3.1 按键
        • 3.1.1 基础
        • 3.1.2 硬件电路
        • 3.1.3 软件实现
      • 3.2 传感器
        • 3.2.1 基础
        • 3.2.2 硬件电路
        • 3.2.3 软件实现
    • 4. 总结

1. GPIO 简介

✔️ 输出:用于驱动 LED,蜂鸣器,模拟通信协议数据
✔️ 输入:用于读取按键输入,传感器输入采集,ADC电压采集,模拟通信协议数据

1.1 基本结构

① 整体结构

内核对寄存器置位实现读写,包含输入和输出寄存器

② GPIO位结构

输出时还可通过位寻址对寄存器和 RAM 进行位设置。总结输出模式如下表所示:

模式数据寄存器P-MOSN-MOS输出电平说明
推挽1✔️❌1具有驱动能力
推挽0❌✔️0具有驱动能力
开漏1不可用❌R∞高阻态
开漏0不可用✔️0低电平驱动
关闭不可用不可用不可用❌输入模式
开漏应用:

① 作为通信协议的驱动方式,例如 I2C,可避免多机通信的相互干扰
② io 口接 5V 的上拉时,如果为 R∞,则可输出 5V 的电平

1.2 模式

通过 GPIO 端口配置寄存器,可以影响寄存器和驱动器,实现以下一些模式。
1️⃣ 浮空/上拉/下拉输入

2️⃣ 模拟输入


💡 GPIO 无效,引脚直接接入内部 ADC

3️⃣ 推挽输出

4️⃣ 开漏输出

5️⃣ 复用功能


💡 复用功能,输出来源于片上外设,可以查看stm32的参考手册,8.1.11节有片上外设的GPIO推荐配置

1.3 寄存器

1.3.1 端口功能配置寄存器

端口配置低寄存器定义如下所示,每个端口由 4 位进行控制。

1.3.2 数据输入寄存器

高位保留,低 16 位可直接读出。

1.3.3 数据输出寄存器

高位保留,低 16 位可读可写。

1.3.4 位设置/位清除寄存器

高 16 位用于清除,低 16 位用于设置,使用时写1即可。

1.3.5 位清除寄存器

高位保留,使用时写1即可。

1.4 库函数

在 stm32f10x_gpio.c 和 stm32f10x_rcc.c 中,有以下函数

/* 时钟相关 */voidRCC_AHBPeriphClockCmd(uint32_tRCC_AHBPeriph,FunctionalState NewState);voidRCC_APB2PeriphClockCmd(uint32_tRCC_APB2Periph,FunctionalState NewState);voidRCC_APB1PeriphClockCmd(uint32_tRCC_APB1Periph,FunctionalState NewState);/* GPIO相关函数 */voidGPIO_DeInit(GPIO_TypeDef*GPIOx);/* 复位GPIO */voidGPIO_AFIODeInit(void);/* 复位AFIO */voidGPIO_Init(GPIO_TypeDef*GPIOx,GPIO_InitTypeDef*GPIO_InitStruct);/* 用GPIO_InitStruct初始化GPIOx */voidGPIO_StructInit(GPIO_InitTypeDef*GPIO_InitStruct);/* 结构体变量赋默认值 */uint8_tGPIO_ReadInputDataBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);/* 读函数: */uint16_tGPIO_ReadInputData(GPIO_TypeDef*GPIOx);/* 读函数: */uint8_tGPIO_ReadOutputDataBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);/* 读函数: */uint16_tGPIO_ReadOutputData(GPIO_TypeDef*GPIOx);/* 读函数: */voidGPIO_SetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);/* 写函数:设置高电平 */voidGPIO_ResetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);/* 写函数:设置低电平 */voidGPIO_WriteBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin,BitAction BitVal);/* 写函数:设置高低电平 */voidGPIO_Write(GPIO_TypeDef*GPIOx,uint16_tPortVal);/* 写函数:设置端口 */voidGPIO_PinLockConfig(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);/* 未使用 */voidGPIO_EventOutputConfig(uint8_tGPIO_PortSource,uint8_tGPIO_PinSource);/* 未使用 */voidGPIO_EventOutputCmd(FunctionalState NewState);/* 未使用 */voidGPIO_PinRemapConfig(uint32_tGPIO_Remap,FunctionalState NewState);/* 未使用 */voidGPIO_EXTILineConfig(uint8_tGPIO_PortSource,uint8_tGPIO_PinSource);/* 未使用 */voidGPIO_ETH_MediaInterfaceConfig(uint32_tGPIO_ETH_MediaInterface);/* 未使用 */

2. GPIO 输出及应用

具体函数使用方法,可参考 固件库使用手册

2.1 led 灯

2.1.1 基础

单向导通,长脚+短脚-,小脚+大脚-。

2.1.2 硬件电路
一般低电平强驱动,高电平弱驱动,因此选择此种接法。
2.1.3 软件实现

使用正点原子精英板,LED0 接在 PB5,LED1 接在 PE5,低电平点亮。
LED 流水灯:

#include"stm32f10x.h"// Device header#include"delay.h"/* 定义 LED 端口数组 */uint16_tled_ports[]={GPIO_Pin_0,GPIO_Pin_1,GPIO_Pin_5,GPIO_Pin_4};intmain(void){/* 1. 在rcc.h中定义了总线配置,外设时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);/* 2. 配置IO口模式 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);uint8_ti=0;/* 用于循环 */uint8_tsize=sizeof(led_ports)/sizeof(led_ports[0]);while(1){/* 3. 库函数置位,gpio.h */for(uint8_tj=0;j<size;j++){GPIO_WriteBit(GPIOA,led_ports[j],Bit_SET);/* 关闭所有 LED */}GPIO_WriteBit(GPIOA,led_ports[i],Bit_RESET);/* 循环点灯 */Delay_ms(500);i++;if(i>=size){i=0;}}}

GPIO使用的一般步骤:设置时钟 → 设置mode → 点灯

2.2 蜂鸣器

2.2.1 基础

▪️ 有源:自带振荡源,频率固定
▪️ 无源:需提供振荡脉冲,根据脉冲频率,发出不同声音

2.2.2 硬件电路


PNP 型,基极低电平触发;NPN 型,基极高电平触发。基极和发射极之间需要一定电压,因此负载接在另一侧。

2.2.3 软件实现

使用正点原子精英板,beep 接在 PB8,高电平触发。

#include"stm32f10x.h"#include"delay.h"intmain(void){/* 1. 在rcc.h中定义了总线配置,外设时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);/* 2. 配置IO口模式 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStruct);while(1){/* 3. 库函数置位,gpio.h */GPIO_ResetBits(GPIOB,GPIO_Pin_8);Delay_ms(100);GPIO_SetBits(GPIOB,GPIO_Pin_8);Delay_ms(100);GPIO_ResetBits(GPIOB,GPIO_Pin_8);Delay_ms(100);GPIO_SetBits(GPIOB,GPIO_Pin_8);Delay_ms(700);}}

3. GPIO 输入及应用

3.1 按键

3.1.1 基础

按下导通,松手断开,同时由于是机械触点,有按键抖动需要消抖。

3.1.2 硬件电路


一般采用上面两种方式,key 下接的方式,按下为低电平,io口设置IPU方式

3.1.3 软件实现

使用正点原子精英板,KEY0 接在 PE4,KEY1 接在 PE3,按下为低电平;LED0 接在 PB5,LED1 接在 PE5,低电平点亮。使得 KEY0 控制 LED0 , KEY1 控制 LED1
main.c:

#include"stm32f10x.h"#include"delay.h"#include"led.h"#include"key.h"/* 变量定义 */uint8_tkeyNum=0;intmain(void){/* 1. led and key init */ledInit();keyInit();while(1){keyNum=getKeyNum();/* 接线时注意,短的接mcu */switch(keyNum){case3:led1_Turn();break;case4:led0_Turn();break;default:break;}}}

led.c:

#include"stm32f10x.h"/* 灯选择参数 */#defineLED00#defineLED11/* 开关状态参数 */#defineLED_ON0#defineLED_OFF1voidledInit(void){/* 1. 在rcc.h中定义了总线配置,外设时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);/* 2. 配置IO口模式 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;GPIO_Init(GPIOB,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;GPIO_Init(GPIOE,&GPIO_InitStruct);/* 3. 先关闭 */GPIO_SetBits(GPIOB,GPIO_Pin_5);GPIO_SetBits(GPIOE,GPIO_Pin_5);}/** * @brief LED控制函数 * @param led : 灯选择 (LED0 / LED1) * @param state : 开关状态 (LED_ON / LED_OFF) * @note 低电平点亮 */voidled_set(uint8_tled,uint8_tstate){/* 根据灯选择确定端口和引脚 */GPIO_TypeDef*port;uint16_tpin;switch(led){caseLED0:port=GPIOB;pin=GPIO_Pin_5;break;caseLED1:port=GPIOE;pin=GPIO_Pin_5;break;default:return;/* 非法参数直接返回 */}/* 根据状态设置电平:低电平点亮,高电平熄灭 */if(state==LED_ON){GPIO_ResetBits(port,pin);/* 输出低电平,点亮 */}else{GPIO_SetBits(port,pin);/* 输出高电平,熄灭 */}}/* led turn on or off */voidled0_Turn(void){if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5)==0){led_set(LED0,LED_OFF);}else{led_set(LED0,LED_ON);}}/* 状态翻转 */voidled1_Turn(void){if(GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5)==0){led_set(LED1,LED_OFF);}else{led_set(LED1,LED_ON);}}

key.c:

#include"stm32f10x.h"#include"delay.h"/* key init */voidkeyInit(void){/* 1. 在rcc.h中定义了总线配置,外设时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);/* 2. 配置IO口模式 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_4;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOE,&GPIO_InitStruct);}/* 哪个按键按下 */uint8_tgetKeyNum(void){uint8_tkeyNum=0;if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==0)/* 按键按下 */{Delay_ms(20);while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==0);Delay_ms(20);keyNum=3;}if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==0)/* 按键按下 */{Delay_ms(20);while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)==0);Delay_ms(20);keyNum=4;}returnkeyNum;}

3.2 传感器

3.2.1 基础

传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出。

3.2.2 硬件电路

传感器电路如下所示:

3.2.3 软件实现

使用正点原子精英板,beep 接在 PB8,高电平触发;PA4 引脚外接光传感器。
光敏传感器控制蜂鸣器:

#include"stm32f10x.h"#include"delay.h"/* bee init */voidbeeInit(void){/* 1. 在rcc.h中定义了总线配置,外设时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);/* 2. 配置IO口模式 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStruct);/* 3. 先关闭 */GPIO_ResetBits(GPIOB,GPIO_Pin_8);}/* sensor init */voidsensorInit(void){/* 1. 在rcc.h中定义了总线配置,外设时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);/* 1. 配置IO口模式 */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);}uint8_tlightSensorGet(void){returnGPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);/* 读取光敏的数据输出 */}intmain(void){/* 1. led and key init */beeInit();sensorInit();while(1){if(lightSensorGet()==1)/* 光线暗,电阻大,分压多,输出为1 */{GPIO_SetBits(GPIOB,GPIO_Pin_8);}else{GPIO_ResetBits(GPIOB,GPIO_Pin_8);}}}/* 逆时针电阻变小,顺时针变大 */

现象:遮光时,输出高电平,蜂鸣器响,do 指示灯熄灭


4. 总结

GPIO 使用方法,可参考。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 2:15:23

4平台6.4万饰品|Steam挂刀行情站跑通流程

4平台6.4万饰品&#xff5c;Steam挂刀行情站跑通流程 【免费下载链接】SteamTradingSiteTracker Steam 挂刀行情站 —— 24小时更新的 BUFF & IGXE & C5 & UUYP & ECO 挂刀比例数据 | Track cheap Steam Community Market items on buff.163.com, igxe.cn, c5g…

作者头像 李华
网站建设 2026/10/23 2:13:26

YimMenuV2:GTA 5 增强版菜单工具完整部署指南与功能实战教程

YimMenuV2&#xff1a;GTA 5 增强版菜单工具完整部署指南与功能实战教程 【免费下载链接】YimMenuV2 Experimental menu for GTA 5: Enhanced 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenuV2 如果你刚上手 GTA 5 增强版&#xff0c;最想做的往往是三件事&…

作者头像 李华
网站建设 2026/10/23 2:12:45

【Kali 渗透测试】漏洞学习笔记

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华