目录
1、什么是GPIO
2、GPIO的作用
3、GPIO的基本结构
4、GPIO引脚的基本结构
5、GPIO端口模式的配置
1. 输入浮空(Input Floating)
2. 输入上拉(Input Pull-Up)
3. 输入下拉(Input Pull-Down)
4. 模拟输入(Analog Input)
5. 开漏输出(Open-Drain Output)
6. 推挽式输出(Push-Pull Output)
7. 推挽式复用功能(Alternate Function Push-Pull)
8. 开漏复用功能(Alternate Function Open-Drain)
6、GPIO重映射
7、GPIO配置的相关寄存器
1、端口配置低寄存器(GPIOx_CRL):
2、端口配置高寄存器(GPIOx_CRH):
3、端口是输入数据寄存器(GPIOx_IDR):
4、端口输出数据寄存器(GPIOx_ODR):
5、端口位设置/清除寄存器(GPIOx_BSSR):
6、端口位清除寄存器(GPIOx_BRR):
7、端口配置锁定寄存器(GPIOx_LCKR):
8、示例
1、开启对应的时钟
2、配置GPIO
3、改变GPIO的数据寄存器
1、什么是GPIO
GPIO(General Purpose Input/Output)是一种通用的输入输出接口,广泛应用于微控制器和单板计算机(如树莓派、Arduino等)。GPIO可以配置为输入或输出,用于控制和读取各种外部设备,比如传感器、开关、LED灯等。
总得来说GPIO是引脚,但是不是所有的引脚都是GPIO
2、GPIO的作用
输出:输出模式下可以控制输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序
输入:输入模式下可以读取端口的高低电平或电压,用于读取按键的输入、外界模块电平信号输入、ADC电压采集、模拟通信协议接收数据等
3、GPIO的基本结构
在STM32中,所有的GPIO都是挂载在APB2外设总线上的,每个GPIO外设各有16个引脚
4、GPIO引脚的基本结构
5、GPIO端口模式的配置
stm32f10x系列芯片举例
从芯片手册可以知道,GPIO有八种模式
1. 输入浮空(Input Floating)
- 功能:引脚处于高阻态,不连接时不会对电路产生影响。此模式适用于读取外部信号。
- 应用:常用于读取开关状态或传感器信号,但在未连接时可能导致引脚浮动,易受干扰。
2. 输入上拉(Input Pull-Up)
- 功能:引脚通过内置的上拉电阻连接到VDD(正电源),未连接时引脚保持高电平。
- 应用:常用于确保输入引脚在未连接时不处于浮动状态,防止误触发。例如,在按钮按下时,读取高电平(按钮未按下时为高电平)。
3. 输入下拉(Input Pull-Down)
- 功能:引脚通过内置的下拉电阻连接到地(GND),未连接时引脚保持低电平。
- 应用:类似上拉输入,常用于确保输入引脚在未连接时保持低电平状态。例如,在按钮按下时,读取低电平(按钮未按下时为低电平)。
4. 模拟输入(Analog Input)
- 功能:引脚被配置为模拟模式,适用于模拟信号的读取,如ADC(模拟数字转换器)的输入。
- 应用:用于连接传感器(如温度传感器、光传感器等),读取模拟信号并转换为数字值。
5. 开漏输出(Open-Drain Output)
- 功能:引脚可以输出低电平(逻辑0),未驱动时引脚处于高阻态。需要外部上拉电阻来将未驱动状态下的引脚拉到高电平。
- 应用:适用于多点连接的信号线(如I2C总线),多个设备可以共享一条线路,避免信号冲突。
6. 推挽式输出(Push-Pull Output)
- 功能:引脚可以输出高电平(逻辑1)或低电平(逻辑0),能够驱动外部负载。
- 应用:用于控制LED、继电器等外部设备,广泛应用于数字输出场景。
7. 推挽式复用功能(Alternate Function Push-Pull)
- 功能:引脚配置为复用模式,能够支持特定外设(如USART、SPI等)的推挽输出。
- 应用:用于数字通信接口,将引脚设置为特定外设的输出引脚。
8. 开漏复用功能(Alternate Function Open-Drain)
- 功能:引脚配置为复用模式,能够支持特定外设(如I2C)的开漏输出。
- 应用:适用于多点连接场景,允许多个设备在同一线路上通信,避免信号冲突。
6、GPIO重映射
GPIO重映射:为了使不同器件封装外设I/O的数量达到最优,可以把一些复用功能重新映射到其他引脚上。设置复用重映射和调试I/O配置寄存器(AFIO_MAPR)实现引脚的重新映射。这时,复用功能不再映射到它们的原始分配上。
7、GPIO配置的相关寄存器
1、端口配置低寄存器(GPIOx_CRL):
配置低八位引脚工作模式的寄存器
2、端口配置高寄存器(GPIOx_CRH):
配置高八位引脚工作模式的寄存器
3、端口是输入数据寄存器(GPIOx_IDR):
保存输入数据的寄存器
4、端口输出数据寄存器(GPIOx_ODR):
设置输出数据的寄存器
5、端口位设置/清除寄存器(GPIOx_BSSR):
对端口位置1和置0的寄存器
6、端口位清除寄存器(GPIOx_BRR):
设置端口位置0的寄存器
7、端口配置锁定寄存器(GPIOx_LCKR):
当执行正确的写序列设置了位16时,这个寄存器可以用来锁定端口的配置,位[15:0]用于锁定GPIO端口的配置,当相应的端口位执行了LOCK序列之后,在下次系统复位前讲不能再更改端口位的配置。每个锁定位锁定口控制寄存器(CRL、CRH)中相应的四个位
8、示例
好的,讲了这么多,各位应该很好奇,那到底应该怎么配置呢,跟着我的步伐,手把手教你配置GPIO
1、开启对应的时钟
从第3点的图中,我们可以知道,GPIO的时钟来自APB2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
这个函数就是标准库为我们封装好的配置APB2时钟的函数
这个函数在stm32f10x_rcc.h中
如果是我一个的keil开发,可以右键这个函数,
第一个就是跳转倒函数的定义
第二个是跳转到函数的声明
/*** @brief Enables or disables the High Speed APB (APB2) peripheral clock.* @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.* This parameter can be any combination of the following values:* @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,* RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,* RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,* RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,* RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,* RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,* RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11 * @param NewState: new state of the specified peripheral clock.* This parameter can be: ENABLE or DISABLE.* @retval None*/
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{/* Check the parameters */assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));assert_param(IS_FUNCTIONAL_STATE(NewState));if (NewState != DISABLE){RCC->APB2ENR |= RCC_APB2Periph;}else{RCC->APB2ENR &= ~RCC_APB2Periph;}
}
这就是配置APB2的函数声明,我们选择参数填入
2、配置GPIO
GPIO_Init(GPIOB,&GPIOB_struct);
调用这个函数,继续跳转函数定义
/*** @brief Initializes the GPIOx peripheral according to the specified* parameters in the GPIO_InitStruct.* @param GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that* contains the configuration information for the specified GPIO peripheral.* @retval None*/
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
看注释,第一个参数容易,那么第二个参数怎么办呢??一样,选中参数类型跳转定义
/** * @brief GPIO Init structure definition */typedef struct
{uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.This parameter can be any value of @ref GPIO_pins_define */GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.This parameter can be a value of @ref GPIOSpeed_TypeDef */GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
ok,就是一个tepedef的结构体,那我们自己定义一个结构体出来就可以了
GPIO_InitTypeDef GPIOB_struct;GPIOB_struct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 |GPIO_Pin_14;GPIOB_struct.GPIO_Speed = GPIO_Speed_50MHz;GPIOB_struct.GPIO_Mode = GPIO_Mode_Out_PP;
将这个结构体放在GPIO_IInit函数前面定义出来就OK,每一个成员是什么,应该怎么幅值,看注释和继续类型跳转就ok
比如GPIO_Mode,就点击前面的类型GPIOMode_TypeDef跳转至
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_Mode就ok了
到此为止GPIO就配置完成
3、改变GPIO的数据寄存器
GPIO_SetBits(GPIOB,GPIO_Pin_12);
这个函数就可以将GPIOB-12的电平拉高
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
这个函数就可以将GPIOB-12的电平拉低
ok,至此,配置寄存器以及GPIO输出高低电平便已完成,外接一个需要电平的led,我们拉高和拉低电平,便可以实现点灯与灭灯