stm32f4一共有七组IO,GPIOA-GPIOG,每组IO有16个口,PAx,x为0-15
GPIO框图
保护二极管: IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于VDD_FT时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁
上拉、下拉电阻:控制引脚默认状态的电压,开启上拉的时候引脚默认电压为高电平,开启下拉的时候引脚默认电压为低电平
TTL施密特触发器:基本原理是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;IO口信号经过触发器后,模拟信号转化为0和1的数字信号 也就是高低电平 并且是TTL电平协议 这也是为什么STM32是TTL电平协议的原因
P-MOS管和N-MOS管:信号由P-MOS管和N-MOS管,依据两个MOS管的工作方式,使得GPIO具有“推挽输出”和“开漏输出”的模式 P-MOS管高电平导通,低电平关闭,下方的N-MOS低电平导通,高电平关闭
GPIO的工作模式
四种输入
GPIO_Mode_IN_FLOATING 浮空输入
GPIO_Mode_IPU 上拉输入
GPIO_Mode_IPD 下拉输入
GPIO_Mode_AIN 模拟输入
四种输出
GPIO_Mode_Out_OD 开漏输出(带上拉或下拉)
GPIO_Mode_AF_OD 复用开漏输出(带上拉或下拉)
GPIO_Mode_Out_PP 推挽输出(带上拉或下拉)
GPIO_Mode_AF_PP 复用推挽输出(带上拉或下拉)
各个工作模式的特点
工作模式 | 工作特点 |
---|---|
浮空输入 | IO口的电平信号直接进入输入数据寄存器,MCU直接读取IO口电平,完全由外部输入决定 |
上拉输入 | IO内部接上拉电阻,默认高电平,IO如果输入低电平,则读取到低电平 |
下拉输入 | IO内部接下拉电阻,默认低电平,IO如果输入高电平,则读取到高电平 |
模拟输入 | 用作ADC采集电压,不经过施密特触发器,直接进入ADC模块,输入寄存器为空,不能从输入寄存器读取引脚状态 |
上下拉电阻不起作用,即使配置上下拉模式,也不影响模拟信号的输入输出 | |
开漏输出(带上拉或下拉) | 只有N-MOS工作,如果输出低电平,则端口为低电平,输出高电平,由外部上下拉电阻决定,如果没有上下拉,则为悬空状态 |
此时施密特触发器打开,输入可用,可通过输入寄存器IDR读取IO实际状态,IO电平不一定是输出电平 | |
推挽输出(带上拉或下拉) | N-MOS、P-MOS都工作,输出低就是低,输出高就是高,外接上下拉只是控制没有输出时IO口电平 |
此时施密特触发器打开,输入可用,可通过输入寄存器IDR读取IO实际状态,IO电平一定是输出电平 | |
复用开漏输出(带上拉或下拉) | GPIO复用为其他外设,输出寄存器ODR无效,输出电平来源于其他外设, |
输入可用,可通过IDR读取IO实际状态 | |
除输出来源有区别,其他与开漏输出一致 | |
复用推挽输出(带上拉或下拉) | GPIO复用为其他外设,输出寄存器ODR无效,输出电平来源于其他外设, |
输入可用,可通过IDR读取IO实际状态 | |
除输出来源有区别,其他与推挽输出一致 |
各个工作模式的一般使用场景
工作模式 | 工作特点 |
---|---|
浮空输入 | |
上拉输入 | 用来检测外部信号,如按键等 |
下拉输入 | |
模拟输入 | ADC模拟输入、低功耗省电 |
开漏输出(带上拉或下拉) | 应用于I2C,SMBUS等需要“线与”功能的总线电路中 |
推挽输出(带上拉或下拉) | 一般用于输出电平0V与3.3V需要高速切换的场合,比较常用 |
复用开漏输出(带上拉或下拉) | 片内外设功能(I2C的SCL、SDA) |
复用推挽输出(带上拉或下拉) | 片内外设功能(TX1、MOSI、MISO、SCK、SS) |
STM32F4的GPIO_InitTypeDef结构体
typedef struct
{
uint32_t GPIO_Pin; //要配置的GPIO管脚
GPIOMode_TypeDef GPIO_Mode; //指定管脚的操作模式
typedef enum
{
GPIO_Mode_IN = 0x00, //GPIO输入模式
GPIO_Mode_OUT = 0x01, //GPIO输出模式
GPIO_Mode_AF = 0x02, //GPIO复用模式
GPIO_Mode_AN = 0x03 //GPIO模拟模式
}GPIOMode_TypeDef
GPIOSpeed_TypeDef GPIO_Speed; //指定管脚的速度
typedef enum
{
GPIO_Low_Speed = 0x00, //低速 2MHZ
GPIO_Medium_Speed = 0x01, //中速 25MHZ
GPIO_Fast_Speed = 0x02, //快速 50MHZ
GPIO_High_Speed = 0x03 //高速 100MHZ
}GPIOSpeed_TypeDef;
GPIOOType_TypeDef GPIO_OType; //指定管脚的操作输出类型
typedef enum
{
GPIO_OType_PP = 0x00,//推挽输出
GPIO_OType_OD = 0x01// 开漏输出
}GPIOOType_TypeDef;
GPIOPuPd_TypeDef GPIO_PuPd; //指定管脚操作上拉/下拉
typedef enum
{
GPIO_PuPd_NOPULL = 0x00,//浮空
GPIO_PuPd_UP = 0x01,//上拉
GPIO_PuPd_DOWN = 0x02//下拉
}GPIOPuPd_TypeDef;
}GPIO_InitTypeDef;
GPIO配置流程
void XXX_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APH1PerphClockCmd(端口,enable);//具体函数需要根据端口挂载在哪个总线上
配置GPIO_InitTypeDef结构体的五个参数;
GPIO_Init(端口,结构体);
}