1.什么是GPIO?
GPIO全称general purpose input output及通用输入输出端口,负责采集信息或者控制外部器件工作。
2.GPIO特点
1.不同型号,IO口数量可能不一样,可通过选型手册快速查询
2.快速翻转,每次翻转最快只需要两个时钟周期(F1最高速度可以到50Mhz)
3.每个I0口都可以做中断(51单片机只有两个基本的中断int0和int1)
4.支持8种工作模式
3.GPIO八种工作模式
1、浮空输入GPIO_IN_FLOATING ——浮空输入 UART_RXD
2、带上拉输入GPIO_IPU—— Input Pull-Up
3、带下拉输入GPIO_IPD—— Input Pull-Down
4、模拟输入GPIO_AIN ——Analog Input
5、开漏输出GPIO_OUT_OD Open-Drain 低电平才有驱动能力,对应引脚为1时为高阻态
6、推挽输出GPIO_OUT_PP Push-Pull 能真正的输出高电平和低电平,在两种电平下都具有驱动能力。
7、复用功能的推挽输出GPIO_AF_PP Alternate Function,PP = Push-Pull
8、复用功能的开漏输出GPIO_AF_OD Alternate Function,OD = Open-Drain
复用指的是CPU通过其他片上外设间接控制GPIO引脚的输出,只有输出模式才有复用模式。
与复用相对应的是通用输出模式,通用指的是CPU直接控制GPIO。
4.GPIO的最大输出速度
因为GPIO输出高电平有上升沿,输出低电平有下降沿,当上升沿和下降沿完全重合时就不能输出有效的高低电平。所以上升时间和下降时间限制了GPIO的输出速度,所以我们可以缩短上升沿和下降沿的时间,让斜坡更陡,这样我们就可以加快GPIO的输出速度。STM32一共有三种最大输出速度可以选:
5.初始化GPIO
//RCC_APB2Periph_GPIOA指的是哪些引脚,GPIOA指的是最小系统板的A0-A15引脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能时钟
GPIO_InitTypeDef GPIO_InitStruct;
//设置初始化参数
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //Pull Push 推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All ;//GPIO_Pin_0指的是A0口,这里的ALL指的是所有端口
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA , &GPIO_InitStruct);//初始化,
6.常用的输入输出函数
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //拉高,也就是1
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//拉低,也就是0
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
7.GPIO读取按键状态实例
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIOInitStructure;
GPIOInitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIOInitStructure.GPIO_Pin = GPIO_Pin_1;
GPIOInitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB , &GPIOInitStructure);
while(1)
{
if(GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_1) == 0)
{
Delay_ms(20);
while(GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_1) == 0);
Delay_ms(20);
i+=10;
Servo_SetAngle(i);
}
}