news 2026/7/6 1:30:49

GPIO详细介绍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GPIO详细介绍

一.GPIO是什么

GPIO = 单片机通用引脚,用来输出高低电平、读取外部电平,是单片机和硬件交互最基础的通道。


二. 输入输出模式

2.1、 输入类(4 种)

浮空输入 :引脚无上下拉,悬空时电平随机,仅适合外部自带驱动的信号。

上拉输入 :内部接上拉电阻,默认高电平,按键检测最常用。

下拉输入 :内部接下拉电阻,默认低电平。

图1 上拉输入/下拉输入(两个差不多只是上电默认电平不同)

模拟输入 :关闭数字电路,专供 ADC 电压采集,不能做普通 IO。

图2 模拟输入

2.2、通用输出类(2 种)

推挽输出:高低电平都能驱动,驱动 LED、指示灯首选。

D:漏极 G:栅极 S:源极

N-MOS(下管):栅极电压 > 源极电压(Source接地,即0V)时导通。也就是说,给栅极高电平(1,如3.3V),NMOS就导通。

PMOS(上管):栅极电压<源极电压(Source接VDD,即3.3V)时导通。也就是说,必须给栅极低电平(0,如0V),PMOS才导通。下面两个分别是推挽模式写入高低电平的电流走向图:

图3 推挽输出 置1

图4 推挽输出 置0

为什么电平到输出控制那里变成相反的电平了,因为输出控制那个位置串联着一个反相器(非门)所以变成相反的电平了


开漏输出:只能主动拉低,高电平需要外部上拉,多用于总线通讯。

在开漏输出模式中P-MOS是不工作的,N-MOS又只能输出低电平,在写入1(高电平)时VG==VS,N-MOS管截止,这个时候I/O口属于高阻态的状态,想要输出高电平必须要自己外接上拉电阻。

高阻态(High-Z):这是引脚内部驱动器的状态。指的是芯片内部的 N-MOS 和 P-MOS 全部截止(关闭),导致引脚内部与 VDD 和 VSS 完全断开。这是个“电路动作”,描述的是“芯片有没有在干活”。

为什么非要“外接”而不用内部的?
因为内部上拉电阻阻值太大(40kΩ),驱动能力极弱。在 I2C 高速通信(400kHz 或更快)时,这么大的电阻加上线路寄生电容,会导致上升沿极其缓慢(波形变“钝”),造成通信时序错乱。
所以,外部上拉电阻通常选用 2kΩ ~ 10kΩ(阻值越小,上升沿越快,但功耗越大)。这在硬件电路设计时是必须外挂的元器件。下面是开漏输出的写入低电平的电流走向图:

图5 开漏输出

2.3、复用外设输出类(2 种)

复用推挽输出:引脚分配给串口、定时器 PWM 等外设,推挽驱动。

复用推挽、复用开漏的 MOS 驱动电路结构和普通推挽 / 开漏完全一致,区别仅在于驱动信号来源不同:普通模式由 CPU 写输出寄存器控制,复用模式由片上外设直接输出信号控制,软件寄存器不再干预引脚电平。下面是复用推挽输出的写入高电平的电流走向图:

图6 复用推挽输出

复用开漏输出:外设复用 + 开漏,典型用于 I2C 总线。


三、编写驱动程序

3.1、介绍部分寄存器(GPIO、RCC)

3.1.1、APB2 外设时钟使能寄存器(RCC_APB2ENR)

它是挂载在APB2总线上的所有外设(GPIO、USART1、ADC1等)的“总电闸”——复位后默认全部关闭,使用前必须通过该寄存器把对应位置1打开时钟。

3.1.2、端口配置低寄存器(GPIOx_CRL) (x=A..E)

它用 4 个位(共 32 位)控制一个引脚,同时决定了该引脚是输入/输出、输出速度、以及推挽/开漏/复用/模拟等具体模式。这是配置该GPIO的低8位引脚

高两位CNFy[1:0],低二位MODEy[1:0]

3.1.3、端口配置高寄存器(GPIOx_CRH) (x=A..E)

它用 4 个位(共 32 位)控制一个引脚,同时决定了该引脚是输入/输出、输出速度、以及推挽/开漏/复用/模拟等具体模式。这是配置该GPIO的高8位引脚

高两位CNFy[1:0],低二位MODEy[1:0]

3.1.4、端口输入数据寄存器(GPIOx_IDR) (x=A..E)

这是一个“只读”寄存器,它的 16 个有效位(Bit0~Bit15)直接反映了 GPIO 引脚 Px0~Px15 当前的实时电平状态(高/低)。 你读到的 1 就是高电平(3.3V),读到的 0 就是低电平(0V)。

3.1.5、端口输出数据寄存器(GPIOx_ODR) (x=A..E)

它是一个“可读可写”的寄存器,向对应位写入 1 让引脚输出高电平(3.3V),写入 0 让引脚输出低电平(0V)。 但写入的效果取决于当前引脚的模式:推挽输出时直接驱动电压,开漏输出时只能控制拉低,而在输入模式下它另有妙用(控制上下拉)。

3.1.6、端口位设置/清除寄存器(GPIOx_BSRR) (x=A..E)

这是一个 32 位的“只写”寄存器(读回值无效),低 16 位用来将对应引脚输出高电平,高 16 位用来将对应引脚输出低电平。 向任意位写 1 执行动作,写 0 则无影响。最核心的优势是:一条硬件指令即可完成置位或清零,绝对原子,永不被打断。

3.1.7、端口位清除寄存器(GPIOx_BRR) (x=A..E)

这是一个 32 位的“只写”寄存器,只有低 16 位有效(对应 Px0~Px15)。向某个位写 1,对应引脚就被拉低为 0V;写 0 则无任何影响。 它和 BSRR 配合,构成了 F10x 下原子操作 GPIO 的“黄金搭档”。

3.1.8、端口配置锁定寄存器(GPIOx_LCKR) (x=A..E)

一旦按特定序列锁定,GPIO 引脚的模式配置(输入/输出/复用等)就会被硬件冻结,直到下次复位前都无法再修改。 它像一个保险开关,专门用来防止关键引脚的配置被意外篡改。

3.2、STM32编程

我们今天的任务是使用STM32F103C8T6最小系统板,点亮一个led灯让其进行闪烁,在原理图上led灯连接的是PC13低电平点亮,所以我们控制PC13一直产生一个高低电平即可

3.2.1、寄存器编程

先找到外设基地址,打开STM32f10x-中文参考手册,在储存器映射这里最下面就是外设基地址也是APB1的基地址

直接写在代码里面

/*片上外设基地址 */ #define PERIPH_BASE ((unsigned int)0x40000000) #define APB1PERIPH_BASE PERIPH_BASE

一下是APB2和AHB的基地址,AHB原本应该用0x40018000的我们这边为了方便使用0x40020000

/*APB2 总线基地址 */ #define APB2PERIPH_BASE (PERIPH_BASE+0x10000) /* AHB总线基地址 */ #define AHBPERIPH_BASE (PERIPH_BASE+0x20000)

找到GPIOC的外设基地址

/*GPIOC外设基地址*/ #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)

GPIO的寄存器我们只使用到了GPIOC_CRH,GPIOC_ODR,直接用宏定义#define定义用GPIOC的外设基地址加上我们要使用到的寄存器的偏移地址就可以了

/* GPIOC寄存器地址,强制转换成指针 */ #define GPIOC_CRH *(unsigned int *)(GPIOC_BASE + 0x04) #define GPIOC_ODR *(unsigned int *)(GPIOC_BASE + 0x0C)

除了以上的几个寄存器还是不够的,我们还需要启动该GPIO的时钟

因为RCC是在AHB上面,所以我们用AHB的基地址加上RCC的基地址,然后再加RCC_APB2ENR

寄存器的偏移地址就可以了

(unsigned int *):强制转换成无符号32位的指针类型

*:解引用(找到地址里的数据)

/*RCC外设基地址*/ #define RCC_BASE (AHBPERIPH_BASE + 0x1000) /*RCC的AHB1时钟使能寄存器地址,强制转换成指针*/ #define RCC_APB2ENR *(unsigned int *)(RCC_BASE + 0x18)

主函数文件夹

#include "stm32f10x.h" void Delay(unsigned int us) { for(volatile unsigned int y = 0;y < us;y++) { ; } } /** * 主函数 */ int main(void) { // 开启GPIOC 端口时钟 RCC_APB2ENR |= (1<<4); //先清空控制PC13的端口位 GPIOC_CRH &= ~( 0x0F<< (4*5));//~( 0x0F<< (4*5)) == 1111 1111 0000 1111 | 1111 1111 1111 1111 // 然后再配置PC13为通用推挽输出,速度为10M GPIOC_CRH |= (0x01<<4*5); // PC13 输出 低电平 GPIOC_ODR &= ~(1<<13); while(1) { // PC13 输出 高电平 GPIOC_ODR |= (1<<13); //直接操控ODR来置位/清零可能会被中断打断不安全 //可以用下面这这两个寄存器来做置位/清零 //GPIOC_BSRR = (1 << 13); // 高电平 //GPIOC_BRR = (1 << 13); // 低电平 (F10x 专用) // //延时 Delay(0xffff); // P13 输出 低电平 GPIOC_ODR &= ~(1<<13); //延时 Delay(0xffff); } } // 函数为空,目的是为了骗过编译器不报错 void SystemInit(void) { ; }

3.2.2、标准库操作

#include "stm32f10x.h" // Device header //延时 void Delay(unsigned int us) { for(volatile unsigned int y = 0;y < us;y++) { ; } } int main(void) { //启动GPIOC的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //创建一个GPIO的初始化结构体 GPIO_InitTypeDef GPIO_InitStructure; //使用推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //使用PC13 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //速度配置为50MHz GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //以上程序还没有写入GPIOC的寄存器的 //GPIO_Init将刚刚配置的全部写到寄存器 GPIO_Init(GPIOC, &GPIO_InitStructure); while (1) { //PC13置零 GPIO_ResetBits(GPIOC, GPIO_Pin_13); //延时 Delay(0xffff); //PC13置零 GPIO_SetBits(GPIOC, GPIO_Pin_13); //延时 Delay(0xffff); } }

上面大部分图片来源为《STM32F10x-中文参考手册》


如果你觉得有帮助,欢迎点赞、收藏、评论,让更多人看到!

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

汽车软件测试,难点到底在哪?

代码规模大、修改频繁&#xff0c;回归测试成本极高 功能安全要求高&#xff0c;但测试覆盖和合规证明难以量化 标准多且复杂&#xff0c;人工检查容易遗漏 项目节奏快&#xff0c;测试往往成为瓶颈&#xff0c;而不是保障 更现实的一点是&#xff1a;不是工程师不够努力&…

作者头像 李华
网站建设 2026/7/3 23:28:28

2026年7月零代码网站搭建与企业无代码建站工具测评:谁更适合你,

一、四个建站工具总表 品牌建站方式更适合谁价格工具特点案例方向BBWEYYAISAAS覆盖5000行业包括零售、工厂、外贸、本地生活700元-3000元一年&#xff0c;买3送3年&#xff0c;年均降至350-1500元/年&#xff0c;每月还配有5-7折的优惠名额&#xff0c;年费至低降至175元/年彻…

作者头像 李华
网站建设 2026/7/5 19:56:31

手机AI Agent系统级集成实战:从架构到代码的完整指南

大家好&#xff0c;我是专注于技术实战分享的博主。最近在探索AI Agent的落地场景时&#xff0c;发现一个普遍存在的误区&#xff1a;很多人一提到“手机AI Agent”&#xff0c;就立刻想到开发一个独立的App。这其实是一个典型的“方向错了”的思维定式。手机作为现代人最贴身、…

作者头像 李华
网站建设 2026/7/5 8:25:14

告别信息过载:利用聚合平台的 Grok 模型快速提炼长文章核心观点

在信息爆炸的今天&#xff0c;职场人每天都要面对动辄上万字的行业研报、技术文档和竞品分析。传统的“硬读”模式不仅耗费大量时间&#xff0c;还容易让人抓不住重点。为了提高效率&#xff0c;不少科技从业者开始使用具备强逻辑与长文本处理能力的 Grok 模型进行长文摘要。如…

作者头像 李华
网站建设 2026/7/5 10:55:59

英伟达“技术没有秘密“合理吗:研发总监拆解护城河的真相

文章目录前言一、先还原现场&#xff1a;媒体是怎么断章取义的二、CUDA确实公开&#xff1a;英伟达恨不得你全学会三、能做出显卡和能做出好显卡&#xff0c;是两回事四、最有发言权的&#xff0c;是那些没说英伟达没技术的对手五、补充一个关键前提&#xff1a;这里说的是算力…

作者头像 李华
网站建设 2026/7/5 6:56:05

Dify实战教程:从零搭建企业级AI应用,掌握低代码开发与工作流设计

这次我们来看一个关于 Dify 的实战教程资源。这个标题指向的是一套旨在帮助开发者快速掌握 Dify 平台&#xff0c;并完成企业级 AI 应用搭建的系列课程。对于想要入门低代码 AI 应用开发&#xff0c;或者希望将 AI 能力快速集成到业务中的团队和个人来说&#xff0c;这类系统性…

作者头像 李华