当前位置: 首页 > ops >正文

GPIO 输入/输出

目录

什么是 GPIO?

GPIO基本结构

GPIO位结构​

GPIO模式

使用 SPL 操作 GPIO 的三个步骤

硬件电路


什么是 GPIO?

        在 STM32 微控制器中,GPIO(General Purpose Input/Output,通用输入输出口) 是最基本、最常用的外设之一。它的主要作用是控制单片机引脚的电平状态,因此被广泛用于与外部设备进行交互,并且是实现各种外设功能的基础。

        GPIO 引脚具备高度的可配置性,支持多种不同的工作模式,以适应不同的应用需求,主要包括以下几种:
输入模式:将引脚配置为输入状态,用于读取外部的电平信号。例如,可以用来检测按键是否被按下,或读取来自传感器、外部模块的数字电平。
输出模式:将引脚配置为输出状态,可以输出高电平(3.3V)或低电平(0V),以控制外部设备的工作。例如点亮或熄灭 LED,驱动蜂鸣器,或产生模拟通信的时序信号。
复用功能模式(Alternate Function):当 GPIO 引脚不再用于普通输入/输出时,可以将其交由其他外设控制,例如作为串口(USART)、定时器(TIM)、SPI 或 I²C 接口的引脚。这种模式下,GPIO 引脚成为对应外设功能的一部分。
模拟功能模式(Analog):将引脚配置为模拟模式,可用于连接模数转换器(ADC),实现模拟信号的采集,例如电压测量、传感器模拟输出等。

        综上,GPIO 是 STM32 控制和感知外部世界的桥梁,几乎参与所有的外设操作。

GPIO基本结构

左侧紫色:APB2 总线
全称:Advanced Peripheral Bus 2(高级外设总线 2)
功能:连接 CPU 和 GPIO 外设
STM32F1 系列中,GPIO 属于 APB2 总线挂载的外设,因此使用 RCC->APB2ENR 寄存器来开启它的时钟。

橙色块:GPIO 外设模块(如 GPIOA、GPIOB)
STM32 会有多个 GPIO 端口模块,分别对应 GPIOA、GPIOB、GPIOC……等,每个端口负责 16 个引脚(Px0 ~ Px15)。
每个 GPIO 模块内部有两大部分:
1. 寄存器模块
用于 CPU 配置 GPIO 的各项功能(输入/输出模式、上拉/下拉、速度、输出类型等)
常用的寄存器有:
CRL / CRH(配置模式)
IDR(输入数据)
ODR(输出数据)
BSRR / BRR(快速位操作)
LCKR(锁定配置)
CPU 通过访问这些寄存器来控制 GPIO 的工作状态。

2. 驱动器模块
实际电气驱动电路,用于控制 GPIO 引脚输出高电平/低电平,或接收外部电平信号。
分为:
推挽输出:高低电平切换,能驱动电流
开漏输出:只能下拉,需外部上拉电阻
输入:读取外部状态
这些电路决定了 GPIO 的真实“电气行为”。

右侧绿色块:物理引脚
如:PA0--PA15、PB0--PB15
每个 GPIO 模块最多支持 16 个物理引脚(对应编号 0~15)
这些是在开发板上用跳线连接的实体引脚

图中流程
1. CPU 通过 APB2 总线 访问 GPIO 外设
2. 配置 GPIOA / GPIOB 等模块中的寄存器
3. 寄存器控制驱动器
4. 驱动器作用于实际的引脚

GPIO位结构

这张图是 STM32 GPIO 引脚的硬件结构原理图,官方称为 I/O端口位的基本结构。它揭示了每个引脚(如 PA0、PB5)在硬件层面是怎么工作的。

右侧:I/O 引脚电路部分(物理接口)
I/O 引脚
图最右边的 I/O 引脚 即实际芯片上的某个引脚(如 PA13)
所有控制输入/输出行为最终都作用在这个引脚上。

上下保护二极管
两个 钳位保护二极管 分别接到 VDD 和 VSS(电源和地),用于:
防止电压过高击穿器件
限制输入电压范围(通常在 VSS - 0.3V ~ VDD + 0.3V 之间)

中间:输入/输出驱动电路
TTL肖特基触发器(上边的三角符号)
把引脚的电平转换成数字电平(高/低),传输给内部逻辑电路。
只有当 I/O 被设置为输入模式时才工作。

上下拉电阻(右边的开关电阻)
可以选择上拉到 VDD 或下拉到 VSS(由 GPIO_PUPDR 寄存器控制)
避免输入引脚悬空造成不稳定状态

输出驱动控制器(最下面的 P-MOS + N-MOS)
控制电平输出,决定是推挽输出、开漏输出还是高阻态
有一个 输出控制模块 根据寄存器配置选择不同工作模式:
推挽输出:P-MOS/N-MOS 交替导通,能输出高/低电平
开漏输出:只拉低,需外部上拉电阻拉高
关断:输出关闭,进入高阻态(常用于输入模式)

上拉(Pull-up)和下拉(Pull-down)是 GPIO 作为输入模式时的两种状态配置,用于解决外部信号未连接时的 悬空 问题:
上拉:通过内部电阻将引脚默认拉到高电平(VDD,如 3.3V)。如果外部没有输入信号(引脚悬空),引脚会稳定在高电平;当外部输入低电平时,引脚被拉低。
下拉:通过内部电阻将引脚默认拉到低电平(GND,0V)。如果外部没有输入信号,引脚会稳定在低电平;当外部输入高电平时,引脚被拉高。

推挽(Push-Pull)描述的是输出电路的工作方式,由两个互补的晶体管(或 MOS 管)组成:
当输出高电平时,上方的晶体管导通( 电流流出引脚,提供高电平)
当输出低电平时,下方的晶体管导通( 电流流入引脚,接地形成低电平)
这种结构能主动输出高电平和低电平,驱动能力强(可提供较大电流),因此叫推挽—— 像两个人一推一拉,能稳定输出两种电平。

开漏(Open-Drain)中的  指 MOS 管的漏极(Drain)。输出电路仅包含一个漏极接引脚的 MOS 管,源极接地:
当输出低电平时,MOS 管导通,引脚通过管子接地(输出 0V)
当输出高电平时,MOS 管截止,引脚与内部电路断开(开漏 状态),此时引脚电压由外部上拉电阻决定(通常接 VDD,输出 3.3V)
只能下拉 是指:内部电路只能主动将引脚拉到低电平,高电平无法主动输出,必须依赖外部电阻 拉上去

左侧:数据控制逻辑(寄存器区)
输入数据寄存器(IDR)
连接输入触发器,读取引脚电平状态

输出数据寄存器(ODR)
控制引脚输出电平

输出控制逻辑
从 MCU 内部总线接收指令,通过 多路复用器(MUX)选择复用输出或 GPIO 输出

置位/清除寄存器(BSRR/BRR)
快速设置/清除某个引脚的高低电平,避免读改写出错
BSRR(双向寄存器):
高 16 位:写 1 时清除对应引脚(例如第 16 位写 1 → 引脚 0 输出 0);
低 16 位:写 1 时置位对应引脚(例如第 0 位写 1 → 引脚 0 输出 1);
写 0 时无操作,因此可通过一条指令同时控制多个引脚 。
置位就是变为1,清除就是变为0

复用与模拟输入
图中还包括了 复用功能输入/输出 路径(如串口、定时器等)
模拟输入 是指 ADC 使用该引脚时,跳过数字电路,直接连接到模数转换模块

回顾这张图,只需要知道以下几点即可:
每个 GPIO 引脚都可以是输入或输出,背后都有电路支持
上拉/下拉电阻用于稳定输入状态,防止悬空
输出模式分推挽和开漏,有不同电路行为
所有操作都是靠访问寄存器来控制这些开关电路
GPIO 也可以被外设复用(UART、ADC、PWM)

GPIO模式

通过配置 GPIO 的端口配置寄存器,端口可以配置成以下8种模式

使用 SPL 操作 GPIO 的三个步骤

第一步:开启 GPIO 时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

第一个参数表示哪个外设(GPIOA、USART1…)
第二个参数 ENABLE / DISABLE 表示是否开启

第二步:配置 GPIO 模式

GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;           // PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   // 输出速度
GPIO_Init(GPIOA, &GPIO_InitStructure);

使用 GPIO_Init() 对引脚进行一次性配置

第三步:读/写 GPIO 电平

GPIO_SetBits(GPIOA, GPIO_Pin_0);    // PA0 输出高电平
GPIO_ResetBits(GPIOA, GPIO_Pin_0);  // PA0 输出低电平// 或读取
uint8_t state = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);

硬件电路

高电平点亮型电路(LED 阳极接 3.3V)

PA0 输出低电平点亮 LED

低电平接地型电路(LED 阴极接 GND)

PA0 输出高电平点亮 LED

PNP 型三极管(S8550)驱动电路

电路结构:
使用的是 PNP 型三极管(S8550)
三极管的 发射极接 3.3V
负载(如蜂鸣器)接在集电极与地之间
PA0 通过 R1 控制基极(电流限流)

PA0 输出低电平时,三极管导通,负载工作。

NPN 型三极管(S8050)驱动电路

电路结构:
使用的是 NPN 型三极管(S8050)
三极管的 发射极接地
负载(如蜂鸣器)接在 3.3V 与集电极之间
PA0 通过 R1 控制基极

PA0 输出高电平时,三极管导通,负载工作。

传感器信号采集模块电路原理图

LM393 比较器部分(左侧)
元器件:
U1: LM393 双路电压比较器
C1: 去耦电容,用于电源滤波
功能:
将输入信号(IN+ 与 IN-)进行比较
如果 IN+ > IN-,输出 高电平
如果 IN+ < IN-,输出 低电平
输出引脚为 DO(Digital Output)

电压比较输入部分(中左)
元件说明:
R2: 设定阈值的电位器或分压电阻,接到 IN-
N1: 传感器元件(如光敏电阻、热敏电阻、红外管)
R1: 上拉电阻,用于与传感器组成电压分压回路
IN+: 来自分压点的模拟电压
工作原理:
N1(传感器)电阻随外部物理量(光、热、红外)变化
与 R1 构成分压,形成 IN+ 电压信号
与设定好的 IN- 电压进行比较
比较器根据高低判断输出 DO(0/1)

模拟信号输出(AO)
AO 是从 R1 与 N1 的中点直接引出的 分压电压
它表示当前传感器输出的连续电压值
可以接 STM32 的 ADC 引脚读取


尚未完结

http://www.xdnf.cn/news/15450.html

相关文章:

  • 2025年睿抗机器人开发者大赛CAIP-编程技能赛-高职组(省赛)解题报告 | 珂学家
  • 在Autodl服务器中使用VNC建立图形界面
  • 快速排序:原理、示例与 C 语言实现详解
  • C语言---自定义类型(下)(枚举和联合类型)
  • 云服务器如何管理数据库(MySQL/MongoDB)?
  • 【html常见页面布局】
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | DoubleClickHeart(双击爱心)
  • netstat -tlnp | grep 5000
  • Swift实现股票图:从基础到高级
  • python的形成性考核管理系统
  • 并发-原子变量类
  • 【MCU控制 初级手札】1.1 电阻
  • 现代CSS实战:用变量与嵌套重构可维护的前端样式
  • 使用 Java 获取 PDF 页面信息(页数、尺寸、旋转角度、方向、标签与边框)
  • Flink双流实时对账
  • 大语言模型零样本情感分析实战:无需机器学习训练,96%准确率实现指南
  • 云手机隐私保护指南:如何保障账号与数据的云端安全?
  • 虚拟机删除操作
  • IELTS 阅读C15-test1-passage 2 复盘
  • React源码6 三大核心模块之一:commit, finishConcurrentRender函数
  • 24.找到列表中最大或最小值的索引
  • Pitaya 是一个简单、快速、轻量级的游戏服务器框架,它为分布式多人游戏和服务器端应用程序提供了一个基本的开发框架
  • 优雅的Java:01.数据更新如何更优雅
  • Python学习之路(十二)-开发和优化处理大数据量接口
  • 从springcloud-gateway了解同步和异步,webflux webMvc、共享变量
  • S7-200 SMART PLC:不同CPU及数字量 IO 接线全解析
  • 构建强大的物联网架构所需了解的一切
  • Janitor AI重塑人机交互的沉浸式智能体验
  • 大型语言模型(LLM)的技术面试题
  • 【机器人】REGNav 具身导航 | 跨房间引导 | 图像目标导航 AAAI 2025