GPIO
1.GPIO概述
-
GPIO (General Purpose Input Output)通用输入输出接口
作用:采集外部器件的信息或控制外部器件工作
GPIO的8种模式 特点和应用 浮空输入 输入用,电平不确定 上拉输入 输入用,I/O脚默认高电平 下拉输入 输入用,I/O脚默认低电平 模拟功能 ADC模拟输入,DAC输出 开漏输出 软件IIC的SDA、SCL等 推挽输出 驱动能力强,25mA(MAX) 开漏式复用 片上外设(IIC的SDA、SCL等) 推挽式复用 片上外设(SPI的SCK、MISO等)
2.原理图
2.1 保护二极管:保护电路,防止外部电压过高或过低输入,只有输入电压不低于Vss且不大于Vdd二极管才导通。
2.2 上下拉电阻:阻值通常在30-50kΩ,是弱上拉或者下拉,当引脚未连接外部设备时,通过上接电源或者下接地来确定电平,上拉为高电平,下拉为低电平。
作用:防止悬空状态,因为悬空易受环境的电磁干扰。
2.3 施密特触发器:将非标准方波整形成方波,广泛用于信号整形和去除噪声的电路中。
- 当输入电压高于正向阈值电压,输出为高;
- 当输入电压低于负向阈值电压,输出为低;
- 当输入在正负向阈值电压之间,输出不改变
- 具有滞回特性(输出状态改变后,输入必须越过相反方向的阈值才改变);去抖动能力(防止由于输入信号微小的噪声引起的频繁输出变化)。
2.4 P-MOS和N-MOS管
通过控制硼极电压Vg来实现MOS管的开关作用(G是硼极,S是源极,D是漏极)
P-MOS:当Vgs<0是,导通
N-MOS: 当Vgs>0是,导通
3.GPIO的八种模式
3.1 浮空输入
I/O引脚 -> TTL施密特触发器 -> 数据数据寄存器 -> 读出
- 上下拉电阻断开,输出驱动被禁止
- 此时I/O的电平完全由外部电路决定。若未连接外部设备,输入的电平不稳定。所以此模式可以检验外部引脚电平情况。
3.2 上拉输入
I/O引脚 ->(上拉电阻导通 )-> TTL施密特触发器 -> 数据数据寄存器 -> 读出
- 上拉电阻导通,下拉电阻断开
- 此时I/O引脚空闲状态为高电平
3.3 下拉输入
I/O引脚 ->(下拉电阻导通 )-> TTL施密特触发器 -> 数据数据寄存器 -> 读出
- 上拉电阻导通,下拉电阻断开
- 此时I/O引脚空闲状态为低电平
3.4 模拟输入
I/O引脚 -> 模拟输入
TTL施密特触发器关闭,上下拉电阻断开
用于ADC采集,另外一个DAC输出是另外一条线直接模拟输出->I/O引脚(图中未标出)
3.5 开漏输出
写入 -> 位设置/清除寄存器 ->输出数据寄存器 ->输出控制 -> N-MOS(可选) -> I/O引脚
- 由于施密特触发器打开,I/O 引脚的电平状态会被采集到输入数据寄存器中,所以此模式也可对I/O读数据。
- 通过设置输出数据寄存器(ODR)的相应位写0,经过输出控制非逻辑门来控制N-MOS管导通或截止。
- 由于P-MOS一直截止,所以电路不存在I/O引脚接到VDD,即不能输出高电平。
- 当N-MOS导通时,漏极开路,由于源极接地,输出引脚与地导通输出低电平。当N-MOS截止时,输出引脚呈现高阻态,必须有外部或内部上拉电阻才输出高电平。
3.6 推挽输出
写入 -> 位设置 /清除寄存器 ->输出数据寄存器 ->输出控制 -> N/P-MOS -> I/O引脚
- 由于施密特触发器打开,所以此模式也可对I/O读数据。
- 通过设置输出数据寄存器(ODR)的相应位,经过输出控制非逻辑门来控制N/P-MOS管导通或截止。
- 当输出逻辑1时,P-MOS截止,N-MOS导通,输出引脚与地导通输出低电平;当输出逻辑为0时,N-MOS截止,P-MOS导通,输出引脚与VDD导通输出高电平。
- 此模式输出高电平时,由于与VDD相连,驱动能力较强,所以可用电流型驱动。最高输出25mA。
3.7 开漏式复用
复用功能输出 ->输出控制 -> N-MOS(可选) -> I/O引脚
- P-MOS截止,施密特触发器打开,上下拉电阻关闭,通过外设来控制N-MOS开关。
- 同理于开漏式输出的电路逻辑,输出低电平,只有外部或内部上拉电阻才输出高电平。
3.8 推挽式复用
复用功能输出-> 输出控制 -> N/P-MOS -> I/O引脚
施密特触发器打开,上下拉电阻关闭,通过外设来控制P/N-MOS开关.
同理于推挽式输出的电路逻辑。
4. 代码配置
void Key_Init(void){
//打开GPIOA引脚时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//结构体初始化
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //引脚选择
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//输出速率
GPIO_Init(GPIOA, &GPIO_InitStructure); //完成设置
}