一、GPIO
主要知识点:
1、通用GPIO概述
2、GPIO的工作方式
3、GPIO的相关寄存器
4、GPIO的应用
5、GPIO的初始化代码
1、GPIO概述:
GPIO是通用输入/输出的简称,是单片机和外界通讯的必要窗口。换句话来说,GPIO就像我们的计算机的显示器和键盘,我们对单片机的读写操作就是通过I/O口来实现的。
2、GPIO的工作方式:
四种输入模式:
浮空输入
上拉输入
下拉输入
模拟输入
四种输出模式:
开漏输出
开漏复用功能
推挽输出
推挽复用功能
四种最大输出速度:
2MHZ
25MHZ
50MHZ
100MHZ
GPIO接口结构图
GPIO的引脚状态:
上电复位后,GPIO默认为浮空状态,部分特殊功能引脚除外。
推挽输出:可以输出强高低电平,连接数字器件
开漏输出:只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)
GPIO的相关寄存器
每组GPIO端口的寄存器包括:
一个端口模式寄存器(GPIOx_MODER)
一个端口输出类型寄存器(GPIOx_OTYPER)
一个端口输出速度寄存器(GPIOx_OSPEEDR)
一个端口上拉下拉寄存器(GPIOx_PUPDR)
一个端口输入数据寄存器(GPIOx_IDR)
一个端口输出数据寄存器(GPIOx_ODR)
一个端口置位/复位寄存器(GPIOx_BSRR)
一个端口配置锁存寄存器(GPIOx_LCKR)
两个复位功能寄存器(低位GPIOx_AFRL & GPIOx_AFRH)
GPIO的应用
以STM32F4为例
1、点亮LED(输出)
第一步原理图
原理图分析:
- 3组IO口A\B\C,每一组16个分别是0~15。
- LED挂接在PC4/5和PB0上面,只要输出低电平,LED点亮。
第二步:输出低电平
根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成八种模式。
- 输入浮空:浮空输入状态下,IO的电平状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平是不确定的。做按键,是要读取电平状态,这种配置抗干扰性差,但是处理信号方面一般是配置这个功能。如测试一个波形,这时候可以配置这个功能。
- 输入上拉:经过电阻连接到VCC,能让IO口在没有连接信号时有一个确定的高电平,并且也能从VCC处获得比较大的驱动电流。
- 输入下拉:经过电阻连接到GND,能让IO口在没有连接信号时有一个确定的低电平。
- 模拟输入:芯片内部外设专用功能(ADC,DAC对应的IO口功能)
- 开漏输出:IO输出0接地,IO输出1悬空,需要外接上拉电阻,才能实现输出高电平。
- 推挽式输出:IO输出0接地,IO输出1接VCC,拥有较强的驱动能力。
- 推挽式复用功能:GPIO口被用作第二功能时的配置情况(即并非作为普通IO口使用),比如像片上外设的UART、SPI模块对应的输出数据线
- 开漏复用功能:GPIO口被用作第二功能时的配置情况(即并非作为普通IO口使用),比如像片上外设的IIC模块对应的数据线和时钟线,使用时要外接上拉电阻。
第三步:模式设置
配置GPIO口需要使用到GPIO初始化函数GPIO_Init,具体描述如下:
typedef struct
{
uint32_t GPIO_Pin; //设置的 GPIO 管脚,使用操作符“|”可以一次选中多个管脚
GPIOMode_TypeDef GPIO_Mode; //设置的 GPIO 管脚模式
GPIOSpeed_TypeDef GPIO_Speed; //设置选中管脚的速率。
GPIOOType_TypeDef GPIO_OType; //设置选中管脚的输出类型。
GPIOPuPd_TypeDef GPIO_PuPd; //设置选中管脚的上下拉。
}GPIO_InitTypeDef;
- GPIO_ResetBits:复位引脚电平,使得引脚输出低电平
- GPIO_SetBits:置位引脚电平,使得引脚输出高电平
示例代码:
2、初始化代码
/**************************************
时间:2024年11月10日08点54分
修改:GPIO初始化
函数名:Gpio_Init()
参数:LED、MOTOR、BEEP
备注:LED1:PC4、LED2:PC5、LED3:PB0
备注:MOTOR:PC8、BEEP:PC12
****************************************/
void Gpio_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct={0};
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);//开启PC时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);//开启PB时钟
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT; //通用输出模式
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; //推挽输出
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_8;//配置4、5、8引脚
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL; //无上下拉
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //速率50M(高速)
GPIO_Init(GPIOC,&GPIO_InitStruct); //初始化GPIOC
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; //配置0引脚
GPIO_Init(GPIOB,&GPIO_InitStruct); //初始化GPIOB
//两种方法任用一种即可
LED1=1; // 初始状态为灭灯(使用位带)
LED2=1;
LED3=1;
GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_4); //初始状态灭灯(调用标准库)
GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5);
GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0);
}
二、配置按键(输入)
老规矩先查看原理图
连接在PA0、PC13、PB1上,并且接有上拉或下拉电阻的,所以配置为浮空输入即可,记得开启对应的外设时钟。
初始化配置
/**************************************
时间:2024年7月16日10点12分
修改:KEY
函数名:KEY初始化
参数:KEY1、KEY2、KEY3
备注:key1:PA0、key2:PC13、key3:PB1
****************************************/
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct={0};
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//开启PC时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN; //输入模式
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL; //无上下拉
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13;
GPIO_Init(GPIOC,&GPIO_InitStruct);
}
按键功能函数
/**************************************
时间:2024年7月16日11点11分
修改:按键消抖
函数名:int Key_Get_Num(void)
参数:KEY1、KEY2、KEY3
备注:key1:PA0、key2:PC13、key3:PB1
****************************************/
int Key_Get_Num(void)
{
int KeyNum=0;
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)//按键按下
{
delay_led(20000); //消抖
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1){;}
delay_led(20000);
KeyNum=1; //按键1
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)
{
delay_led(20000);
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0){;}
delay_led(20000);
KeyNum=3;
}
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)==0)
{
delay_led(20000);
while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)==0){;}
delay_led(20000);
KeyNum=2;
}
return KeyNum; //按键返回值
}
小习题:
实现流水灯
实现花式流水灯
使用按键分别控制流水灯、花式流水灯
标签:输出,Pin,寄存器,基础,STM32,IO,InitStruct,GPIO From: https://blog.csdn.net/qq_56491232/article/details/143651719