stm32——GPIO开发

发布于:2024-11-02 ⋅ 阅读:(9) ⋅ 点赞:(0)

目录

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,我们拉高和拉低电平,便可以实现点灯与灭灯