GPIO
GPIO基本特性
STM32系列微控制器的GPIO(通用输入输出)引脚具有多种工作模式,每种模式都适用于不同的应用需求。主要的GPIO工作方式包括:
输入模式:
- 浮空输入(Floating Input):引脚没有外部上拉或下拉电阻,输入信号的状态不确定。适用于高阻抗的信号读取。
- 上拉输入(Input with Pull-up):内部上拉电阻连接到VCC,输入信号在没有外部信号时被拉高。
- 下拉输入(Input with Pull-down):内部下拉电阻连接到GND,输入信号在没有外部信号时被拉低。
输出模式:
- 推挽输出(Push-Pull Output):引脚可以驱动高电平和低电平,通过内部电路提供较强的驱动能力,适用于大部分通用输出应用。
- 开漏输出(Open-Drain Output):引脚只有低电平输出能力,高电平由外部上拉电阻拉高。适用于I²C总线等需要多个设备共享同一信号线的场景。
复用模式(Alternate Function Mode):
GPIO引脚可以被配置为特定外设的功能,比如定时器、USART、SPI、I²C等。这种模式允许引脚用于实现复杂的外设通信和控制功能。
模拟模式(Analog Mode):
引脚被配置为模拟输入或输出,可以用于ADC(模数转换器)或DAC(数模转换器)。这种模式适用于模拟信号的处理。
每种模式的选择和配置都可以通过STM32的配置寄存器来完成,通常涉及到GPIO的配置寄存器(如GPIOx_MODER、GPIOx_OTYPER、GPIOx_PUPDR等)以及复用功能的寄存器。
从上图中,可以得出推挽输出和开漏输出的特性区别:
图中施密特触发器的作用是产生两个参考电压,一个高参考电压,一个低参考电压。当输入电压高于高参考电压,则输出高电平;当输入电压低于低参考电压则输出低电平;输入电压介于两者之间则维持原电平信号。经过施密特触发器处理的电平信号写入输入数据寄存器,使用GPIO库函数读取电平信号。
输入模式中的上拉、下拉和浮空输入都仅读取高低电平,即数字信号,统称为数字输入。而模拟输入是读取输入信号的具体电压数值,与ADC模块相关。
代码示例
- 以GPIO输出高低电平控制LED灯的亮灭为例
static void ConfigLEDGPIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //GPIO_InitStructure用于存放GPIO的参数
//使能RCC相关时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能GPIOC的时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //设置引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置I/O输出速度
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置推挽输出模式
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据参数初始化LED1的GPIO
GPIO_WriteBit(GPIOC, GPIO_Pin_4, Bit_RESET); //将LED1默认状态设置为熄灭
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //设置引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置I/O输出速度
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置推挽输出模式
GPIO_Init(GPIOC, &GPIO_InitStructure); //根据参数初始化LED2的GPIO
GPIO_WriteBit(GPIOC, GPIO_Pin_5, Bit_RESET); //将LED2默认状态设置为熄灭
}
首先,配置GPIO的相关参数。电路图上与LED1和LED2相连的引脚是PC4和PC5,通过控制这两个引脚输出高低电平来控制LED1和LED2的亮灭。由于LED灯的负极与GND相连,所以只能使用推挽输出。
GPIO引脚的速度设置决定了引脚的切换速度,也影响到引脚驱动能力及功耗。STM32通常提供多种速度设置选项,如 2 MHz、10 MHz、50 MHz 和 100 MHz。50 MHz 的速度设置是一个折中选择,适用于大多数常规应用。如果需要更高的切换速度或者更低的延迟,可能会选择 100 MHz。较高的速度设置可能会导致更多的电磁干扰(EMI)和功耗增加,但提供更快的响应时间。
GPIO_WriteBit(GPIOC, GPIO_Pin_5, Bit_RESET); //LED1熄灭
PC5输出低电平,LED1熄灭,LED2同理。
- 以读取PA0的电平状态为例
static void ConfigGPIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //GPIO_InitStructure用于存放GPIO的参数
//使能RCC相关时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA的时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //设置引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置I/O输出速度
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置输入模式
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA,初始化完成,GPIOA默认为高电平
}
将 GPIO 引脚配置为上拉输入模式。在这种模式下,引脚被配置为输入状态,并且内部有一个上拉电阻使得引脚在没有外部信号时默认处于高电平状态。
u8 Fall_off(void)
{
u8 Fall_off_Flag = 0;
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 0)
Fall_off_Flag = 0; //未脱落
else
Fall_off_Flag = 1; //已脱落
return Fall_off_Flag;
}
这是一个简单的脱落识别函数,当PA0引脚为低电平时,表示未脱落(根据外部电路来规定),反之。