GPIO
GPIO
GPIO(General Purpose Input Output)
GPIO功能描述
STM32的GPIO模块通过软件编程实现I/O端口的重新映射,从而达到I/O端口功能的复用。
GPIO端口的每个位可以由软件分别配置成下列9个模式:
- 浮空输入:当引脚浮空时,相当于介入高电平;
- 上拉输入:将不确定的信号通过一个电阻嵌位在高电平;
- 下拉输入;
- 模拟输入;
- 开漏输出;
- 推挽式输出;
- 复用功能推挽式输出;
- 复用功能开漏输出;
GPIO的基本结构
复用功能
使用默认复用功能前必须对端口位配置寄存器
- 对于复用输入,端口必须配置为输入模式(浮空、上拉或下拉)且输入引脚必须由外部驱动;
- 对于复用输出,端口必须配置为复用输出模式(推挽或开漏);
- 对于双向复用,端口必须配置为复用输出(推挽或开漏),输入驱动器必须配置为浮空输入模式。
输入配置
当I/O端口配置为输入时:
- 输出缓冲器被禁止;
- 出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器IDR中
输出配置
- 输出缓冲器被激活;
- 在开漏模式时,对输入数据寄存器的读访问可得到I/O状态;
- 出现在I/O引脚上的数据在每个ABP2时钟被采样到输出数据寄存器;
- 在推挽模式,对输出寄存器的读访问可得到最后一次写入的值
GPIO常用库函数
-
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
第一个参数确定是哪个GPIO, 第二个参数设置该GPIO的引脚以及引脚的模式和输出最大速度。
第二个参数的结构体为
typedef struct { uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; } GPIO_InitTypeDef;
GPIO_Mode
即之前提到的可配置的九种模式的一个枚举typedef enum { GPIO_Mode_AIN = 0x0, //模拟输入 GPIO_Mode_IN_FLOATING = 0x04, //浮空输入 GPIO_Mode_IPD = 0x28, //下拉输入 GPIO_Mode_IPU = 0x48, //上拉输入 GPIO_Mode_Out_OD = 0x14, //开漏输出 GPIO_Mode_Out_PP = 0x10, //通用推挽输出 GPIO_Mode_AF_OD = 0x1C, //复用开漏输出 GPIO_Mode_AF_PP = 0x18 //复用推挽 }GPIOMode_TypeDef;
函数使用示例:
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Init
函数并不只是在初始化时才调用,每一次需要改变GPIO端口时都需要调用这个函数来完成。 -
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
读取某个GPIO的某个引脚的值,返回结果为一个8位的整型,也就是读取一个字节。下面的函数中,如果没有给出参数,说明参数与本函数一致。
同样的还有读取输出寄存器的值的函数
GPIO_ReadOutputDataBit
,这里不作赘述。 -
GPIO_SetBits
和GPIO_ResetBits
置位和重置位
GPIO案例——跑马灯
跑马灯硬件连接图
/*
* 使用GPIO实现跑马灯
* 库函数的包括就略了
*/
int main() {
GPIO_InitTypeDef GPIO_InitStructure;
delay_init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); //使能PB,PE端口时钟
//配置GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_5); //LED0配置在GPIOB pin5,pin5推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure);//LED1配置在GPIOE pin5
GPIO_SetBits(GPIOE, GPIO_Pin_5);
while (1) {
GPIO_ResetBits(GPIOB, GPIO_Pin_5);
GPIO_SetBits(GPIOE, GPIO_Pin_5);
delay_ms(500); //延迟500ms
GPIO_SetBits(GPIOB, GPIO_Pin_5);
GPIO_ResetBits(GPIOE, GPIO_Pin_5);
delay_ms(500);
}
}
WELCOME TO THE MACHINE