1. GPIO简介
- GPIO(General Purpose Input Output)通用输入输出端口。
- 可配置为8种输入输出模式。
- 引脚电平:0V~3.3V,部分引脚可容忍5V。
- 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等。
- 输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等。
每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。
根据数据手册中列出的每个I/O端口的特定硬件特征, GPIO端口的每个位可以由软件分别配置成多种模式。
- 上拉输入
- 下拉输入
- 浮空输入
- 模拟输入
- 推挽输出
- 推挽复用输出
- 开漏输出
- 开漏复用输出
每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这样,在读和更改访问之间产生IRQ时不会发生危险。
2. GPIO基本结构
系统结构
基本结构
3. GPIO位结构
- 保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入。当引脚电压高于VDD时,上方的二极管导通;当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。
- P-MOS管和N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。这里的电路会在下面很详细地分析到。
- TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号。但是,当GPIO引脚作为ADC采集电压的输入通道时,用其“模拟输入”功能,此时信号不再经过触发器进行TTL电平转换。ADC外设要采集到的原始的模拟信号。
这里需要注意的是,在查看《STM32中文参考手册V10》中的GPIO的表格时,会看到有“FT”一列,这代表着这个GPIO口时兼容3.3V和5V的;如果没有标注“FT”,就代表着不兼容5V。
4. GPIO八种模式
GPIO支持4种输入模式(浮空输入、上拉输入、下拉输入、模拟输入)和4种输出模式(开漏输出、开漏复用输出、推挽输出、推挽复用输出)。同时,GPIO还支持三种最大翻转速度(2MHz、10MHz、50MHz)。
每个I/O口可以自由编程,但I/O口寄存器必须按32位字被访问。
下面将具体介绍GPIO的这八种工作方式:
整个图片分为上下两部分,输入模式对应上半部分,因此只看高亮处。
4.1上拉输入
上拉输入即上面的开关闭合(接Vdd),下面的开关断开(接Vss)。当IO口啥都不接时,单片机读取到的就是Vdd,即高电平,(开关一般用MOS管来实现)因此上拉输入默认读取的就是高电平,即ReadInputDataBit = 1;一般用于检测按键,例如按下按键,模拟检测电路(施密特触发器)就会检测到低电平,从而向单片机MCU传递低电平信号,即ReadInputDataBit = 0;
4.2下拉输入
下拉输入即下面的开关闭合(接Vss),上面的开关断开(接Vdd)。当IO口啥都不接时,单片机读取到的就是Vss,即低电平,(开关一般用MOS管来实现)因此下拉输入默认读取的就是低电平,即ReadInputDataBit = 0;一般用于检测按键,例如按下按键,模拟检测电路(施密特触发器)就会检测到高电平,从而向单片机MCU传递高电平信号,即ReadInputDataBit = 1;
4.3浮空输入
浮空输入即上下连接的Vdd和Vss开关都断开。I/O端口的电平信号直接进入输入数据寄存器,I/O的电平状态是不确定的,完全由外部输入决定;当IO口没有外部输入(悬空)的时候,单片机读取到的值处于不确定状态,即浮动,一会儿1,一会儿0,只有输入了一个高/低电平才会确定下来。因此容易受到外部干扰。
4.4模拟输入
模拟输入即没有上下拉,也没有经过施密特触发器(用于将模拟信号转为0/1),直接把I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等。模拟信号一般:3.3v 5v 9v。因此该模式常用于外部输入电压检测,例如温度传感器、光照传感器;
整个图片分为上下两部分,输出模式对应下半部分,因此只看下半部分高亮处。
4.5推挽输出
推挽模式即“推”和“挽”。
所谓推挽输出的推,就是上面的P-MOS导通,电源Vdd直接接到了IO口给外设供电,电流从Vdd流向IO口(输出高电平,拉电流), 称之为“推”;
所谓推挽输出的挽,就是下面的N-MOS导通,GND(Vss)直接与IO相连,电流可以从IO口流向GND(Vss)(输出低电平,灌电流),称之为“挽”。
因此推和挽就是电流的流向;
万金油模式,可以用于驱动LED、蜂鸣器等;
4.6开漏输出
1. 前置知识
开漏输出的“开”指的是开路,即pmos和nmos都断开,外设相当于什么都没接,就是开路;
“漏”指的是MOS管的漏极输出;
MOS管就像一个水龙头,栅极G就类似于一个水龙头开关,控制MOS管的导通与关断;
(导通原理:对于NMOS,当给栅极高电平时,电子被吸引到栅极附近形成N沟道,因此MOS管导通)
2. 开漏模式介绍
开漏输出有两种输出状态:
- 低电平
- 高阻态
在开漏输出模式下,PMOS一直处于关断状态,只需要关注NMOS管;
(1) 当NMOS导通时,IO口接地,对外输出低电平:
(2)当NMOS也关断时,IO口什么都没接,即单片机输出高阻态
此时外设相当于接了个寂寞,也可以说是开路:
这样看来好像开漏输出没什么用,只能输出低电平,不能输出高电平。
但在某些场景下开漏输出很有用,例如I2C通信协议中,作为SCL和SDA的GPIO口设置必须设置为开漏模式。
由于从设备全部连接到一根线也就是SDA上,那么只要有一个输出低电平,SDA就就被拉低;
但是要想输出高电平怎么办?
方法是外接上拉电阻
- 当外接上拉电阻时,默认情况下就输出高电平,而且这个Vcc由我们自己决定,根据外设需要来确定Vcc;
- NMOS导通时输出低电平;
3. 开漏模式优势和缺点
优点:
- 线与功能,在通信总线中,有一个设备是低电平,总线就被拉低;
- 上拉的电源由我们确定,可以驱动需要大电压的外设;
缺点:
- 高低电平切换速度比推挽输出慢(上拉电阻的阻值和引脚上的负载电容会影响引脚从低电平到高电平的切换速度)
4.7复用推挽输出
先理解一下“复用”:
- 在嵌入式系统和微控制器中,复用(Alternate Function)指的是某些GPIO口除了作为普通输入输出引脚外,还可以被配置为执行其他特定外设功能
复用推挽定义
复用推挽输出 是指将其功能设置为某个特定的复用功能,并将GPIO引脚配置为推挽输出模式
复用推挽模式下引脚的io的操作由相应的功能模块来完成,普通推挽表示你需要通过gpio寄存器来操作引脚
举例:
例如STM32f103c8t6的PA9不仅可以作为普通的GPIO口,还可以作为USART1的TX端(即复用为TX端口)。只需要将PA9设置为复用推挽输出模式,片上外设USART和PA9连上了,就可以通过该端口发送数据了;
1. 为什么不设置为推挽输出?
- 设置成普通推挽的话,GPIO还是受寄存器来控制,USART模块并没有和GPIO打通,不能通过该端口发送信号;
2. 当PA9被配置为复用推挽输出时,单片机内部发生了什么?
- 当配置为复用模式(如 GPIO_Mode_AF_PP)后,GPIO和USART模块在内部连接起来。USART模块的TX信号可以通过配置好的GPIO引脚输出,从而USART和GPIO引脚“打通”了。
4.8复用开漏输出
开启端口的复用功能,由片上外设控制IO口电平,且输出模式为开漏输出
例如配置硬件I2C时,SCL和SDA对应的引脚要配置为复用开漏输出模式,当配置为这种模式时,干了两件事
- 复用PAx为硬件I2C的SDA端口(将 片上外设---硬件I2C 的SDA与该端口打通了)
- 设置该引脚为开漏输出
相应的GPIO口要配置为复用开漏输出,也就是启用这个IO口的复用功能,不把他当成普通IO口用了。
此时由硬件I2C自己来控制IO口的高低电平,如下图: