一. 前言
GPIO全称General Purpose Input Output,是微控制数字输入/输出的基本模块,可以实现微控制器与外部环境的数字进行交换。借助GPIO微控制器可以实现对外围设备(像控制led亮灭,按键控制,软件模拟IIC等)直观又简单的控制。
GPIO的8种模式
1. 输入模式:
(1)上拉输入模式 GPIO_Mode_IPU
(2)下拉输入模式 GPIO_Mode_IPD
(3)模拟输入模式 GPIO_Mode_AIN
(4)浮空输入模式 GPIO_Mode_IN_FLOATING
2. 输出模式:
(1)推挽输出模式 GPIO_Mode_Out_PP
(2)开漏输出模式 GPIO_Mode_Out_OD
(3)复用推挽输出模式 GPIO_Mode_AF_PP
(4)复用开漏输出模式 GPIO_Mode_AF_OD
3. 最大输出速度:
(1)2MHz GPIO_Speed_2MHz
(2)25MHz GPIO_Speed_25MHz
(3)50MHz GPIO_Speed_50MHz
二. 输入模式
输入驱动器
GPIO的输入驱动器主要由TTL肖特基触发器、带开关的上拉电阻和带开关的下拉电阻组成,GPIO的输入驱动器没有多路选择开关,输入信号送到GPIO输入数据寄存器的同时,送给了片上外设,所以GPIO的输入没有复用功能选项。
1. 上拉输入模式
上拉就是把当前引脚的电位拉高,比如拉到VDD。弱上拉和强上拉的区别只是上拉电阻的阻值不同。
输出缓冲器被禁止,TTL施密特触发输入被激活,此时图中GPIO内部上拉电阻端的开关闭合,接通VDD,下拉电阻端开关断开。此时引脚默认输入为高电平。
2. 下拉输入模式
下拉就是把当前引脚的电位拉低,比如拉到GND。
输出缓冲器被禁止,TTL施密特触发输入被激活,此时图中GPIO内部下拉电阻端的开关闭合,接通VSS,上拉电阻端开关断开。此时引脚默认输入为低电平。
3. 模拟输入模式
应用于ADC模拟输入,或者是低功耗下的省电。
输出缓冲器被禁止,TTL施密特触发输入被禁止。
4. 浮空输入模式
浮空就是GPIO输入引脚即不接高电平,也不接低电平。由于逻辑器件的内部结构,当它输入引脚悬空时,相当于该引脚接了高电平。实际运用时,引脚不建议悬空,容易受到干扰。
输出缓冲器被禁止,TTL施密特触发输入被激活,GPIO内部下拉电阻端的开关断开,上拉电阻端开关也断开。
三. 输出模式
输出驱动器
GPIO的输出驱动器主要由多路选择器、输出控制逻辑和一对互补的MOS管组成。多路选择器是根据用户的设置决定某个引脚是输出还是复用功能输出。输出控制逻辑和一对互补的MOS管是根据用户的设置通过控制P-MOS管和N-MOS管的导通还是断开决定GPIO是开漏、推挽输出模式还是关闭。
1. 推挽输出模式
推挽输出既可以输出高电平,也可以输出低电平,连接数字器件。推挽输出的结构一般是指两个三极管分别受到两个互补信号的控制,在一个三极管被导通的时候另一个三极管被截止。输出的高点电平则是由IC的电源决定。
在推挽输出时,N-MOS和P-MOS管都会参与工作。当输出控制输出为0(低电平),则是P-MOS管关闭。N-MOS管导通,这时I/O引脚的电平就是低电平。当输出控制输出为1(高电平),则是P-MOS管导通。N-MOS管关闭,这时I/O引脚的电平就是高电平。
在推挽输出时,施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。
2. 开漏输出模式
开漏模式一般用在IIC等需要“线与”功能的总线电路中,除此之外,还可以用在电平不匹配的场合,像需要输出5V的高电平就可以在外部接入一个上拉电阻,上拉电源为5v,并把GPIO设置为开漏模式,当输出高阻态时,由上拉电源向外部输出5V的电平。
在开漏输出时,只有N-MOS会参与工作,上方的P-MOS管完全不工作。当输出控制为0(低电平)时,P-MOS管关闭,N-MOS管导通,使得输出GND。当输出控制为1(高电平)时,P-MOS管和N-MOS管全部关闭,引脚既不输出高电平也不输出低电平,此时呈现一个高阻态。正常使用的情况下,必须接一个上拉电阻,若不接上拉电阻,则引脚只能输出低电平。
在推挽输出时,施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。
3. 复用推挽输出模式
GPIO复用为其他外设(IIC的SCL,SDA)。除了输出信号的来源改变 ,其他操作与推挽输出的功能相同。
4. 复用开漏输出模式
GPIO复用为其他外设(TX1,MOSI,MISO,SCK,SS)。除了输出信号的来源改变 ,其他操作与开漏输出的功能相同。
四. GPIO的选用
当作为普通GPIO输入:根据需要配置该引脚为浮空、上拉或下拉输入,同时不使能该引脚对应的所有复用功能模块。
当作为普通GPIO输出:根据需要配置该引脚为推挽输出或开漏输出,同时不使能该引脚对应的所有复用功能模块。
当作为普通模拟输入:配置该引脚为模拟输入模式,同时不使能该引脚对应的所有复用功能模块。
当作为内置外设的输入:根据需要配置该引脚为浮空、上拉或下拉输入,同时使能该引脚对应的某个复用功能模块。
当作为内置外设的输出:根据需要配置该引脚为复用推挽输出或复用开漏输出,同时使能该引脚对应的所有复用功能模块。
五. 有关GPIO输入/输出模式的初始化(F1系列 HAL库函数)
GPIO_InitTypeDef 类型的结构体
typedef struct
{
uint32_t Pin; /*!<指定要配置的GPIO引脚。该参数可以是@ref GPIO_pins_define 的任意值 */
uint32_t Mode; /*!<指定所选引脚的工作模式。该参数可以是@ref GPIO_mode_define 的值 */
uint32_t Pull; /*!< 指定所选引脚的上拉或下拉激活。该参数可以是@ref GPIO_pull_define的值 */
uint32_t Speed; /*!< 指定所选引脚的速度。该参数可以是@ref GPIO_speed_define的值 */
} GPIO_InitTypeDef;
可以选择的GPIO引脚
/** @defgroup GPIO_pins_define GPIO pins define
* @{
*/
#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */
#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */
#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */
#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */
#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */
#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */
#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */
#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */
#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */
#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */
#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */
#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */
#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */
#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */
#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */
#define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */
#define GPIO_PIN_MASK 0x0000FFFFu /* PIN mask for assert test */
/**
* @}
*/
可以选择的GPIO引脚模式
/** @defgroup GPIO_mode_define GPIO mode define
* @{
*/
#define GPIO_MODE_INPUT 0x00000000u /*!< 输入模式 */
#define GPIO_MODE_OUTPUT_PP 0x00000001u /*!< 推挽输出模式 */
#define GPIO_MODE_OUTPUT_OD 0x00000011u /*!< 开漏输出模式 */
#define GPIO_MODE_AF_PP 0x00000002u /*!< 复用推挽输出模式 */
#define GPIO_MODE_AF_OD 0x00000012u /*!< 复用开漏输出模式 */
#define GPIO_MODE_AF_INPUT GPIO_MODE_INPUT /*!< 复用功能输入模式 */
#define GPIO_MODE_ANALOG 0x00000003u /*!< 模拟输入模式 */
#define GPIO_MODE_IT_RISING 0x10110000u /*!< 上升沿触发检测的外部中断模式 */
#define GPIO_MODE_IT_FALLING 0x10210000u /*!< 下降沿触发检测的外部中断模式 */
#define GPIO_MODE_IT_RISING_FALLING 0x10310000u /*!< 上升/下降沿触发检测的外部中断模式 */
#define GPIO_MODE_EVT_RISING 0x10120000u /*!< 上升沿触发检测的外部事件模式 */
#define GPIO_MODE_EVT_FALLING 0x10220000u /*!< 下降沿触发检测的外部事件模式 */
#define GPIO_MODE_EVT_RISING_FALLING 0x10320000u /*!< 上升/下降沿触发检测的外部事件模式 */
/**
* @}
*/
可以选择的GPIO引脚上拉/下拉激活
/** @defgroup GPIO_pull_define GPIO pull define
* @brief GPIO Pull-Up or Pull-Down Activation
* @{
*/
#define GPIO_NOPULL 0x00000000u /*!< 没有激活上拉或下拉 */
#define GPIO_PULLUP 0x00000001u /*!< 上拉激活 */
#define GPIO_PULLDOWN 0x00000002u /*!< 下拉激活 */
/**
* @}
*/
可以选择的GPIO引脚的速度
/** @defgroup GPIO_speed_define GPIO speed define
* @brief GPIO Output Maximum frequency
* @{
*/
#define GPIO_SPEED_FREQ_LOW (GPIO_CRL_MODE0_1) /*!< Low speed 低速 */
#define GPIO_SPEED_FREQ_MEDIUM (GPIO_CRL_MODE0_0) /*!< Medium speed 中速 */
#define GPIO_SPEED_FREQ_HIGH (GPIO_CRL_MODE0) /*!< High speed 高速 */
/**
* @}
*/