• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【工程师6】+理论类+STM32的GPIO库函数详解

gpio:通用输入输出接口
gpio管脚:一个io管脚,这个管脚可以有多个配置。在库函数中用GPIO_Pin_1这样的宏定义表示
gpio端口(gpio分组):一组gpio管脚的信息。在库函数中用宏定义GPIOA GPIOB等表示
1      gpio库说明
库文件名:stm32f4xx_gpio.c
文档提示翻译:
如何使用这个驱动
(1)       使用RCC_AHB1PeriphclockCmd(RCC_AHB1Periph_GPIOx, ENABLE)函数使能GPIO的AHB总线时钟
(2)       使用GPIO_Init()函数对每个引脚进行四种可能的配置
《1》       输入状态:Floating(浮空), Pull-up(上拉), Pull-down(下拉)
《2》       输出状态:Push-Pull (上拉下拉)(Pull-up(上拉), Pull-down(下拉) or no Pull(不上拉也不下拉)),Open Drain(开漏) (Pull-up(上拉), Pull-down(下拉) or no Pull(不上拉也不下拉)),在输出模式,速度配置成2MHZ,25MHZ,50MHZ和100MHZ.
《3》       第二功能:上拉下拉和开漏
《4》       模拟:当一个管脚被用作ADC通道或者DAC输出的时候,需要配置成此模式
(3)       外设的第二功能:
《1》       在ADC和DAC模式,使用GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AN把需要的管脚配置成模拟模式
《2》       对于其它的管脚(定时器,串口等):
l  使用GPIO_PinAFConfig()函数把管脚和需要的第二功能进行连接
l  使用GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF把需要的管脚配置成第二功能模式
l  通过成员变量GPIO_PuPd, GPIO_OType and GPIO_Speed选择类型,上拉下拉和输出速度
l  调用函数GPIO_Init()
(4)       在输入模式,使用函数GPIO_ReadInputDataBit()得到配置好管脚的电平
(5)       在输出模式,使用函数GPIO_SetBits()/GPIO_ResetBits()设置配置好IO的高低电平
(6)       在复位过程和刚刚复位后,第二功能是无效的,GPIO被配置成了输入浮空模式(JTAG管脚除外)
(7)       当LSE振荡器关闭的时候,LSE振荡器管脚OSC32_IN和OSC32_OUT可以作为通过IO来使用(分别用PC14和PC15表示)。LSE的优先级高于GPIO函数
(8)       当HSE振荡器关闭的时候,HSE振荡器管脚OSC_IN和OSC_OUT可以作为通用IO(PH0,PH1)来使用。HSE的优先级高于GPIO函数。
全部回复(20)
正序查看
倒序查看
2019-10-18 15:05
2      具体函数说明
初始化和配置相关函数
1.  void GPIO_DeInit(GPIO_TypeDef* GPIOx)
函数解释gpio的反初始化函数,该函数的作用是把GPIO相关的寄存器配置成上电复位后的默认状态,在第一次初始化前或者不再使用某一个接口后可以调用该函数。
函数参数说明:GPIOxgpio的分组,如GPIOA  GPIOB  GPIOC等的宏定义(这些宏定义在头文件stm32f4xx.h中,由厂家写好,我们直接使用即可)

2.  void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef*GPIO_InitStruct)
函数解释gpio的初始化函数,该函数的作用是对io进行初始化。
函数参数说明:(1)GPIOx:gpio的分组,如GPIOA  GPIOB GPIOC等的宏定义。
(2)GPIO_InitStruct:gpio的初始化相关结构体。该结构体里面的成员变量决定了我们具体的初始化参数。以下进行说明:
l  GPIO_Pin:指定具体的IO脚,如GPIO_Pin_0   GPIO_Pin_1这样的宏定义,这些宏由厂家写好,我们直接使用即可。
l  GPIO_Mode:指定gpio的模式,有以下四种模式:
GPIO_Mode_IN(输入),GPIO_Mode_OUT(输出),GPIO_Mode_AF(第二功能),GPIO_Mode_AN(模拟),可以直接使用这四种宏定义。
l  GPIO_Speed:指定IO的最快翻转速度,也就是当使用IO产生频率(如PWM)的最快速度。有以下四种速度的配置:
GPIO_Low_Speed (低速),GPIO_Medium_Speed(中等速度),GPIO_Fast_Speed(快速),GPIO_High_Speed(高速),可以直接使用这四种宏定义。
l  GPIO_OType:指定选择管脚的输出类型,有以下两种配置:
GPIO_OType_PP (推挽方式输出),GPIO_OType_OD(开漏方式输出),可以直接使用这两种宏定义。
Tips:
推挽输出推挽输出就是单片机引脚可以直接输出高电平电压。低电平时接地,高电平时输出单片电源电压。这种方式可以不接上拉电阻。但如果输出端可能会接地的话,这个时候输出高电平可能引发单片机运行不稳定,甚至可能烧坏引脚。推挽方式的驱动力更大。
开漏输出开漏输出就是不输出电压,低电平时接地,高电平时不接地。如果外接上拉电阻,则在输出高电平时电压会拉到上拉电阻的电源电压。这种方式适合在连接的外设电压比单片机电压低的时候。
l  GPIO_PuPd。指定选择管脚的上拉和下拉模式。有如下三种配置:
GPIO_PuPd_NOPULL(不上拉也不下拉),GPIO_PuPd_UP(上拉),GPIO_PuPd_DOWN(下拉)。Tips:这些都是IO的内部上拉或者下拉模式,也可以接上拉和下拉电阻通过硬件进行外部上拉和外部下拉。

3.  void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
函数解释gpio结构体的初始化。对GPIO_InitStruct结构体进行默认配置
函数参数说明:GPIO_InitStruct,直接传入该结构体的指针,在该函数内会对结构体进行初始化。

4.  void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函数解释:锁定gpio的寄存器,锁定的寄存器是GPIOx_MODER,GPIOx_OTYPER, GPIOx_OSPEEDR,GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH。在下一次复位前,被锁定的管脚不能被修改。
函数参数说明:GPIOxgpio的分组(如GPIOA,GPIOB等)。GPIO_Pin:具体的gpio管脚(如GPIO_Pin_0   GPIO_Pin_1这样的宏定义)
0
回复
2019-10-18 15:06
@lihui710884923
2    具体函数说明初始化和配置相关函数1.  voidGPIO_DeInit(GPIO_TypeDef*GPIOx)函数解释:gpio的反初始化函数,该函数的作用是把GPIO相关的寄存器配置成上电复位后的默认状态,在第一次初始化前或者不再使用某一个接口后可以调用该函数。函数参数说明:GPIOx:gpio的分组,如GPIOA  GPIOB  GPIOC等的宏定义(这些宏定义在头文件stm32f4xx.h中,由厂家写好,我们直接使用即可)2.  voidGPIO_Init(GPIO_TypeDef*GPIOx,GPIO_InitTypeDef*GPIO_InitStruct)函数解释:gpio的初始化函数,该函数的作用是对io进行初始化。函数参数说明:(1)GPIOx:gpio的分组,如GPIOA  GPIOBGPIOC等的宏定义。(2)GPIO_InitStruct:gpio的初始化相关结构体。该结构体里面的成员变量决定了我们具体的初始化参数。以下进行说明:l  GPIO_Pin:指定具体的IO脚,如GPIO_Pin_0  GPIO_Pin_1这样的宏定义,这些宏由厂家写好,我们直接使用即可。l  GPIO_Mode:指定gpio的模式,有以下四种模式:GPIO_Mode_IN(输入),GPIO_Mode_OUT(输出),GPIO_Mode_AF(第二功能),GPIO_Mode_AN(模拟),可以直接使用这四种宏定义。l  GPIO_Speed:指定IO的最快翻转速度,也就是当使用IO产生频率(如PWM)的最快速度。有以下四种速度的配置:GPIO_Low_Speed(低速),GPIO_Medium_Speed(中等速度),GPIO_Fast_Speed(快速),GPIO_High_Speed(高速),可以直接使用这四种宏定义。l  GPIO_OType:指定选择管脚的输出类型,有以下两种配置:GPIO_OType_PP(推挽方式输出),GPIO_OType_OD(开漏方式输出),可以直接使用这两种宏定义。Tips:推挽输出:推挽输出就是单片机引脚可以直接输出高电平电压。低电平时接地,高电平时输出单片机电源电压。这种方式可以不接上拉电阻。但如果输出端可能会接地的话,这个时候输出高电平可能引发单片机运行不稳定,甚至可能烧坏引脚。推挽方式的驱动力更大。开漏输出:开漏输出就是不输出电压,低电平时接地,高电平时不接地。如果外接上拉电阻,则在输出高电平时电压会拉到上拉电阻的电源电压。这种方式适合在连接的外设电压比单片机电压低的时候。l  GPIO_PuPd。指定选择管脚的上拉和下拉模式。有如下三种配置:GPIO_PuPd_NOPULL(不上拉也不下拉),GPIO_PuPd_UP(上拉),GPIO_PuPd_DOWN(下拉)。Tips:这些都是IO的内部上拉或者下拉模式,也可以接上拉和下拉电阻通过硬件进行外部上拉和外部下拉。3.  voidGPIO_StructInit(GPIO_InitTypeDef*GPIO_InitStruct)函数解释:gpio结构体的初始化。对GPIO_InitStruct结构体进行默认配置函数参数说明:GPIO_InitStruct,直接传入该结构体的指针,在该函数内会对结构体进行初始化。4.  voidGPIO_PinLockConfig(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin)函数解释:锁定gpio的寄存器,锁定的寄存器是GPIOx_MODER,GPIOx_OTYPER,GPIOx_OSPEEDR,GPIOx_PUPDR,GPIOx_AFRLandGPIOx_AFRH。在下一次复位前,被锁定的管脚不能被修改。函数参数说明:GPIOx:gpio的分组(如GPIOA,GPIOB等)。GPIO_Pin:具体的gpio管脚(如GPIO_Pin_0  GPIO_Pin_1这样的宏定义)
GPIO的读写函数
1.  uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_tGPIO_Pin)
函数解释:读取io输入管脚的值
函数参数说明:GPIOxgpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚
函数返回值说明:输入管脚的值Bit_SET(高电平) Bit_RESET(低电平)

2.  uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
函数解释:读取输入io数据,该函数用于读取一个IO分组的所有数据
函数参数说明:GPIOxgpio的分组/gpio端口
函数返回值说明:一个io端口的所有数据 (输入状态)

3.  uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_tGPIO_Pin)
函数解释:读取io输出管脚的值
函数参数说明:GPIOxgpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚
函数返回值说明:输出管脚的值Bit_SET(高电平) Bit_RESET(低电平)

4.  uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
函数解释:读取输出io分组/端口的值
函数参数说明:GPIOxgpio的分组/gpio端口
函数返回值说明:一个io端口的所有数据 (输出状态)

5.  void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函数解释:对io管脚进行置位(输出高电平)。这个函数使用GPIOx_BSRR寄存器来实现原子读或者修改操作。在这种情况下,在读和修改访问时发生一个IRQ中断是没有危险的。
函数参数说明:GPIOxgpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚或者是io管脚的组合

6.  void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函数解释:对io管脚进行复位(输出低电平)。这个函数使用GPIOx_BSRR寄存器来实现原子读或者修改操作。在这种情况下,在读和修改访问时发生一个IRQ中断是没有危险的。
函数参数说明:GPIOxgpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚或者是io管脚的组合

7.  void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitActionBitVal)
函数解释:对某一位进行写入操作
函数参数说明:GPIOxgpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚;BitVal:写入高电平或者低电平(Bit_RESET:写入低电平 Bit_SET:写入高电平)

8.  void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
函数解释:对gpio端口进行写入操作,适用于对统一端口的多个管脚的写入
函数参数说明:GPIOxgpio的分组/gpio端口; BitVal:写入高电平或者低电平(Bit_RESET:写入低电平 Bit_SET:写入高电平)

9.  void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函数解释:翻转指定的gpio口,也就是说,如果当前的io是低电平,则变成高电平,如果当前io是高电平,则变成低电平
函数参数说明:GPIOxgpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚。
0
回复
2019-10-18 15:07
@lihui710884923
GPIO的读写函数1.  uint8_tGPIO_ReadInputDataBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin)函数解释:读取io输入管脚的值函数参数说明:GPIOx:gpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚函数返回值说明:输入管脚的值Bit_SET(高电平) Bit_RESET(低电平)2.  uint16_tGPIO_ReadInputData(GPIO_TypeDef*GPIOx)函数解释:读取输入io数据,该函数用于读取一个IO分组的所有数据函数参数说明:GPIOx:gpio的分组/gpio端口函数返回值说明:一个io端口的所有数据 (输入状态)3.  uint8_tGPIO_ReadOutputDataBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin)函数解释:读取io输出管脚的值函数参数说明:GPIOx:gpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚函数返回值说明:输出管脚的值Bit_SET(高电平) Bit_RESET(低电平)4.  uint16_tGPIO_ReadOutputData(GPIO_TypeDef*GPIOx)函数解释:读取输出io分组/端口的值函数参数说明:GPIOx:gpio的分组/gpio端口函数返回值说明:一个io端口的所有数据 (输出状态)5.  voidGPIO_SetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin)函数解释:对io管脚进行置位(输出高电平)。这个函数使用GPIOx_BSRR寄存器来实现原子读或者修改操作。在这种情况下,在读和修改访问时发生一个IRQ中断是没有危险的。函数参数说明:GPIOx:gpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚或者是io管脚的组合6.  voidGPIO_ResetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin)函数解释:对io管脚进行复位(输出低电平)。这个函数使用GPIOx_BSRR寄存器来实现原子读或者修改操作。在这种情况下,在读和修改访问时发生一个IRQ中断是没有危险的。函数参数说明:GPIOx:gpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚或者是io管脚的组合7.  voidGPIO_WriteBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin,BitActionBitVal)函数解释:对某一位进行写入操作函数参数说明:GPIOx:gpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚;BitVal:写入高电平或者低电平(Bit_RESET:写入低电平 Bit_SET:写入高电平)8.  voidGPIO_Write(GPIO_TypeDef*GPIOx,uint16_tPortVal)函数解释:对gpio端口进行写入操作,适用于对统一端口的多个管脚的写入函数参数说明:GPIOx:gpio的分组/gpio端口; BitVal:写入高电平或者低电平(Bit_RESET:写入低电平 Bit_SET:写入高电平)9.  voidGPIO_ToggleBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin)函数解释:翻转指定的gpio口,也就是说,如果当前的io是低电平,则变成高电平,如果当前io是高电平,则变成低电平函数参数说明:GPIOx:gpio的分组/gpio端口;GPIO_Pin:具体的gpio管脚。
Gpio复用功能配置函数
1.  void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource,uint8_t GPIO_AF)
函数解释:改变指定管脚的映射关系。即配置指定管脚的复用功能。
函数参数说明:GPIOxgpio的分组/gpio端口;GPIO_PinSource:具体要配置成复用功能的管脚(如GPIO_Pin_0   GPIO_Pin_1这样的宏定义);GPIO_AF:选择该管脚要使用的复用功能。有如下配置:(注意:复用功能的配置要和实际管脚支持的复用功能匹配)
GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin toAF0 (default after reset)
GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2)to AF0 (default after reset)
GPIO_AF_TAMPER: Connect TAMPER pins(TAMPER_1 and TAMPER_2) to AF0 (default after reset)
GPIO_AF_SWJ: Connect SWJ pins (SWD andJTAG)to AF0 (default after reset)
GPIO_AF_TRACE: Connect TRACE pins to AF0(default after reset)
GPIO_AF_TIM1: Connect TIM1 pins to AF1
GPIO_AF_TIM2: Connect TIM2 pins to AF1
GPIO_AF_TIM3: Connect TIM3 pins to AF2
GPIO_AF_TIM4: Connect TIM4 pins to AF2
GPIO_AF_TIM5: Connect TIM5 pins to AF2
GPIO_AF_TIM8: Connect TIM8 pins to AF3
GPIO_AF_TIM9: Connect TIM9 pins to AF3
GPIO_AF_TIM10: Connect TIM10 pins to AF3
GPIO_AF_TIM11: Connect TIM11 pins to AF3
GPIO_AF_I2C1: Connect I2C1 pins to AF4
GPIO_AF_I2C2: Connect I2C2 pins to AF4
GPIO_AF_I2C3: Connect I2C3 pins to AF4
GPIO_AF_SPI1: Connect SPI1 pins to AF5
GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5
GPIO_AF_SPI4: Connect SPI4 pins to AF5
GPIO_AF_SPI5: Connect SPI5 pins to AF5
GPIO_AF_SPI6: Connect SPI6 pins to AF5
GPIO_AF_SAI1: Connect SAI1 pins to AF6 forSTM32F42xxx/43xxx devices.      
GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6
GPIO_AF_I2S3ext: Connect I2S3ext pins toAF7
GPIO_AF_USART1: Connect USART1 pins to AF7
GPIO_AF_USART2: Connect USART2 pins to AF7
GPIO_AF_USART3: Connect USART3 pins to AF7
GPIO_AF_UART4: Connect UART4 pins to AF8
GPIO_AF_UART5: Connect UART5 pins to AF8
GPIO_AF_USART6: Connect USART6 pins to AF8
GPIO_AF_UART7: Connect UART7 pins to AF8
GPIO_AF_UART8: Connect UART8 pins to AF8
GPIO_AF_CAN1: Connect CAN1 pins to AF9
GPIO_AF_CAN2: Connect CAN2 pins to AF9
GPIO_AF_TIM12: Connect TIM12 pins to AF9
GPIO_AF_TIM13: Connect TIM13 pins to AF9
GPIO_AF_TIM14: Connect TIM14 pins to AF9
GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10
GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10
GPIO_AF_ETH: Connect ETHERNET pins to AF11
GPIO_AF_FSMC: Connect FSMC pins to AF12
GPIO_AF_FMC: Connect FMC pins to AF12 forSTM32F42xxx/43xxx devices.   
GPIO_AF_OTG_HS_FS: Connect OTG HS(configured in FS) pins to AF12
GPIO_AF_SDIO: Connect SDIO pins to AF12
GPIO_AF_DCMI: Connect DCMI pins to AF13
GPIO_AF_LTDC: Connect LTDC pins to AF14 forSTM32F429xx/439xx devices.
GPIO_AF_EVENTOUT: Connect EVENTOUT pins toAF15
0
回复
2019-10-18 15:08
@lihui710884923
Gpio复用功能配置函数1.  voidGPIO_PinAFConfig(GPIO_TypeDef*GPIOx,uint16_tGPIO_PinSource,uint8_tGPIO_AF)函数解释:改变指定管脚的映射关系。即配置指定管脚的复用功能。函数参数说明:GPIOx:gpio的分组/gpio端口;GPIO_PinSource:具体要配置成复用功能的管脚(如GPIO_Pin_0  GPIO_Pin_1这样的宏定义);GPIO_AF:选择该管脚要使用的复用功能。有如下配置:(注意:复用功能的配置要和实际管脚支持的复用功能匹配)GPIO_AF_RTC_50Hz:ConnectRTC_50HzpintoAF0(defaultafterreset)GPIO_AF_MCO:ConnectMCOpin(MCO1andMCO2)toAF0(defaultafterreset)GPIO_AF_TAMPER:ConnectTAMPERpins(TAMPER_1andTAMPER_2)toAF0(defaultafterreset)GPIO_AF_SWJ:ConnectSWJpins(SWDandJTAG)toAF0(defaultafterreset)GPIO_AF_TRACE:ConnectTRACEpinstoAF0(defaultafterreset)GPIO_AF_TIM1:ConnectTIM1pinstoAF1GPIO_AF_TIM2:ConnectTIM2pinstoAF1GPIO_AF_TIM3:ConnectTIM3pinstoAF2GPIO_AF_TIM4:ConnectTIM4pinstoAF2GPIO_AF_TIM5:ConnectTIM5pinstoAF2GPIO_AF_TIM8:ConnectTIM8pinstoAF3GPIO_AF_TIM9:ConnectTIM9pinstoAF3GPIO_AF_TIM10:ConnectTIM10pinstoAF3GPIO_AF_TIM11:ConnectTIM11pinstoAF3GPIO_AF_I2C1:ConnectI2C1pinstoAF4GPIO_AF_I2C2:ConnectI2C2pinstoAF4GPIO_AF_I2C3:ConnectI2C3pinstoAF4GPIO_AF_SPI1:ConnectSPI1pinstoAF5GPIO_AF_SPI2:ConnectSPI2/I2S2pinstoAF5GPIO_AF_SPI4:ConnectSPI4pinstoAF5GPIO_AF_SPI5:ConnectSPI5pinstoAF5GPIO_AF_SPI6:ConnectSPI6pinstoAF5GPIO_AF_SAI1:ConnectSAI1pinstoAF6forSTM32F42xxx/43xxxdevices.    GPIO_AF_SPI3:ConnectSPI3/I2S3pinstoAF6GPIO_AF_I2S3ext:ConnectI2S3extpinstoAF7GPIO_AF_USART1:ConnectUSART1pinstoAF7GPIO_AF_USART2:ConnectUSART2pinstoAF7GPIO_AF_USART3:ConnectUSART3pinstoAF7GPIO_AF_UART4:ConnectUART4pinstoAF8GPIO_AF_UART5:ConnectUART5pinstoAF8GPIO_AF_USART6:ConnectUSART6pinstoAF8GPIO_AF_UART7:ConnectUART7pinstoAF8GPIO_AF_UART8:ConnectUART8pinstoAF8GPIO_AF_CAN1:ConnectCAN1pinstoAF9GPIO_AF_CAN2:ConnectCAN2pinstoAF9GPIO_AF_TIM12:ConnectTIM12pinstoAF9GPIO_AF_TIM13:ConnectTIM13pinstoAF9GPIO_AF_TIM14:ConnectTIM14pinstoAF9GPIO_AF_OTG_FS:ConnectOTG_FSpinstoAF10GPIO_AF_OTG_HS:ConnectOTG_HSpinstoAF10GPIO_AF_ETH:ConnectETHERNETpinstoAF11GPIO_AF_FSMC:ConnectFSMCpinstoAF12GPIO_AF_FMC:ConnectFMCpinstoAF12forSTM32F42xxx/43xxxdevices.  GPIO_AF_OTG_HS_FS:ConnectOTGHS(configuredinFS)pinstoAF12GPIO_AF_SDIO:ConnectSDIOpinstoAF12GPIO_AF_DCMI:ConnectDCMIpinstoAF13GPIO_AF_LTDC:ConnectLTDCpinstoAF14forSTM32F429xx/439xxdevices.GPIO_AF_EVENTOUT:ConnectEVENTOUTpinstoAF15
代码示例:
示例一:把gpioa6配置成输出管脚,并配置成高电平
         GPIO_InitTypeDefGPIO_InitStruct;
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
         GPIO_InitStruct.GPIO_Pin= GPIO_Pin_6;
         GPIO_InitStruct.GPIO_Mode= GPIO_Mode_OUT;
         GPIO_InitStruct.GPIO_PuPd= GPIO_PuPd_UP;

         GPIO_Init(GPIOA,&GPIO_InitStruct);

         GPIO_SetBits(GPIOA,GPIO_Pin_6);

示例二:把gpioe4配置成输入
         GPIO_InitTypeDefGPIO_InitStruct;
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
         GPIO_InitStruct.GPIO_Pin= GPIO_Pin_4;
         GPIO_InitStruct.GPIO_Mode= GPIO_Mode_IN;
         GPIO_InitStruct.GPIO_PuPd= GPIO_PuPd_UP;
         GPIO_Init(GPIOE,&GPIO_InitStruct);

示例三:配置复用功能 PA9 PA10 配置成串口1的收发接口
GPIO_InitTypeDef GPIO_InitStructure;
         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能GPIOA时钟
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
         //串口1对应引脚复用映射
         GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);//GPIOA9复用为USART1
         GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//GPIOA10复用为USART1
         //USART1端口配置
         GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9GPIOA10
         GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF;//复用功能
         GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;      //速度50MHz
         GPIO_InitStructure.GPIO_OType= GPIO_OType_PP; //推挽复用输出
         GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP; //上拉
         GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化PA9PA10
0
回复
2019-10-24 08:56
@lihui710884923
代码示例:示例一:把gpioa6配置成输出管脚,并配置成高电平      GPIO_InitTypeDefGPIO_InitStruct;      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);      GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;      GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;      GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;      GPIO_Init(GPIOA,&GPIO_InitStruct);      GPIO_SetBits(GPIOA,GPIO_Pin_6);示例二:把gpioe4配置成输入      GPIO_InitTypeDefGPIO_InitStruct;      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);      GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;      GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;      GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;      GPIO_Init(GPIOE,&GPIO_InitStruct);示例三:配置复用功能 PA9PA10 配置成串口1的收发接口GPIO_InitTypeDefGPIO_InitStructure;      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能GPIOA时钟      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟      //串口1对应引脚复用映射      GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);//GPIOA9复用为USART1      GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//GPIOA10复用为USART1      //USART1端口配置      GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;//GPIOA9与GPIOA10      GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//复用功能      GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;    //速度50MHz      GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽复用输出      GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉      GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化PA9,PA10

对于GPIO口的模式,来个图形详细讲解


浮空输入_IN_FLOATING

带上拉输入_IPU


带下拉输入_IPD

模拟输入_AIN

开漏输出_OUT_OD

推挽输出_OUT_PP

开漏复用输出_AF_OD

推挽复用输出_AF_PP

以下是八种模式的工作原理:




0
回复
2019-10-24 09:12
@lihui710884923
对于GPIO口的模式,来个图形详细讲解带上拉输入_IPU带下拉输入_IPD开漏输出_OUT_OD开漏复用输出_AF_OD以下是八种模式的工作原理:

一.GPIO浮空输入_IN_FLOATING模式工作原理:


以上截图就是浮空输入模式的原理图,图中阴影的部分在浮空输入模式下是处于不工作状态的,尤其是下半部分的输出电路实际上这时的输出电路与输入的端口处于隔离状态。

0
回复
2019-10-24 09:16
@lihui710884923
一.GPIO浮空输入_IN_FLOATING模式工作原理:[图片],

二.GPIO带上拉输入_IPU 模式工作原理:


上图是STM32的GPIO带上拉输入模式的原理图。

与前面介绍的浮空输入模式相比,仅仅是在数据通道上面,接入了一个上拉电阻,根据STM32的数据手册,这个上拉电阻阻值介于30K~50K 欧姆。同样,CPU可以随时在“输入数据寄存器”的另一端,通过内部的数据总线读出I/O 端口的电平变化的状态。



0
回复
2019-10-24 09:18
@lihui710884923
二.GPIO带上拉输入_IPU模式工作原理:[图片]与前面介绍的浮空输入模式相比,仅仅是在数据通道上面,接入了一个上拉电阻,根据STM32的数据手册,这个上拉电阻阻值介于30K~50K欧姆。同样,CPU可以随时在“输入数据寄存器”的另一端,通过内部的数据总线读出I/O端口的电平变化的状态。

三.GPIO带下拉输入_IPD 模式工作原理:


对于输入下拉模式的输入,是在数据通道的下部,接入了一个下拉电阻。

根据STM32的数据手册,这个下拉电阻阻值也是介于30K~50K 欧姆。

对于要加上拉或下拉电阻:

1.当作单片机作为输入时,假设我们直接在IO端口接一个按键到地(或电源)。

因为按键按,于不按管脚都是悬空的。单片机就很难检测按键是否按下。

所以人为的接一个上拉(或下拉)。以确定未按下的时候IO输入电平的状态

2.可以提高芯片的抗干扰能



0
回复
2019-10-24 09:23
@lihui710884923
三.GPIO带下拉输入_IPD模式工作原理:[图片]根据STM32的数据手册,这个下拉电阻阻值也是介于30K~50K欧姆。1.当作单片机作为输入时,假设我们直接在IO端口接一个按键到地(或电源)。所以人为的接一个上拉(或下拉)。以确定未按下的时候IO输入电平的状态

四、GPIO模拟输入_AIN 模式工作原理:


如果把STM32配置为模拟输入模式时,工作原理就比较简单了,信号从左边编号为1 的端口进从右边编号为2的一端直接进入STM32单片机的AD模块。

细心的朋友可以看到数据通道中上拉、下拉电阻和施密特触发器,这时均处于关断的状态,“输入数据寄存器”就不能反映IO端口上的电平变化的状态了,换句话说,也就是在模拟输入状态下,CPU不能通过“输入数据寄存器”读到IO端口变化的数据了。

以上分析的是GPIO模块IO引脚的输入模式的工作原理,下面介绍一下GPIO输出模式的工作原理


0
回复
2019-10-24 09:28
@lihui710884923
四、GPIO模拟输入_AIN模式工作原理:[图片]细心的朋友可以看到数据通道中上拉、下拉电阻和施密特触发器,这时均处于关断的状态,“输入数据寄存器”就不能反映IO端口上的电平变化的状态了,换句话说,也就是在模拟输入状态下,CPU不能通过“输入数据寄存器”读到IO端口变化的数据了。

五、GPIO开漏输出_OUT_OD 模式工作原理


上图是GPIO开漏输出模式的工作原理图

当CPU 在编号1 端通过“位设置/ 清除寄存器”或“输出数据寄存器”写入数据后

该数据位将通过编号2的输出控制电路传送到编号4 的I/O端口。

如果CPU 写入的是逻辑“1 ”,则编号3 的N-MOS管将处于关闭状态

此时I/O 端口的电平将由外部的上拉电阻决定

如果CPU 写入的是逻辑“0 ”,则编号3的N-MOS管将处于开启状态

此时I/O端口的电平被编号3 的N-MOS管拉到了“地”的零电位。

在图中的上半部,施密特触发器处于开启状态

这意味着CPU 可以在“输入数据寄存器”的另一端,随时可以监控I/O端口的状态

通过这个特性,还可以实现了虚拟的I/O端口双向通信:假如CPU 输出逻辑“1 ”

由于编号3 的N-MOS管处于关闭状态,I/O 端口的电平将完全由外部电路决定

因此,CPU 可以在“输入数据寄存器”读到外部电路的信号,而不是它自己输出的逻辑“1 ”


0
回复
2019-10-24 09:28
@lihui710884923
五、GPIO开漏输出_OUT_OD模式工作原理[图片]当CPU在编号1端通过“位设置/清除寄存器”或“输出数据寄存器”写入数据后如果CPU写入的是逻辑“1”,则编号3的N-MOS管将处于关闭状态如果CPU写入的是逻辑“0”,则编号3的N-MOS管将处于开启状态在图中的上半部,施密特触发器处于开启状态通过这个特性,还可以实现了虚拟的I/O端口双向通信:假如CPU输出逻辑“1”因此,CPU可以在“输入数据寄存器”读到外部电路的信号,而不是它自己输出的逻辑“1”

GPIO口的输出模式下,有3 种输出速度可选(2MHz 、10MHz和50MHz) 

这个速度是指GPIO口驱动电路的响应速度,而不是输出信号的速度

输出信号的速度与程序有关(芯片内部在I/O口的输出部分安排了多个响应速度不同的输出驱动电路用户可以根据自己的需要选择合适的驱动电路)。

通过选择速度来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。

高频的驱动电路,噪声很高  

当我们的项目不需要比较高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI 性能。

当然如果我们的项目要求输出较高频率的信号,但却选用了较低频率的驱动模块,很可能会得到比较失真的输出信号

0
回复
2019-10-24 09:33
@lihui710884923
这个速度是指GPIO口驱动电路的响应速度,而不是输出信号的速度通过选择速度来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。当我们的项目不需要比较高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能。

六、GPIO推挽输出_OUT_PP模式工作原理


GPIO的推挽输出模式是在开漏输出模式的基础上,在“输出控制电路”之后,增加了一个P-MOS管

当CPU输出逻辑“1 ”时,编号3 处的P-MOS管导通,而下方的N-MOS管截止,达到输出高电平的目的

当CPU输出逻辑“0 ”时,编号3 处的P-MOS管截止,而下方的N-MOS管导通,达到输出低电平的目的

在这个模式下,CPU 仍然可以从“输入数据寄存器”读到该IO端口电压变化的信号


0
回复
2019-10-24 09:36
@lihui710884923
六、GPIO推挽输出_OUT_PP模式工作原理[图片]当CPU输出逻辑“1”时,编号3处的P-MOS管导通,而下方的N-MOS管截止,达到输出高电平的目的在这个模式下,CPU仍然可以从“输入数据寄存器”读到该IO端口电压变化的信号

七、GPIO开漏复用输出_AF_OD模式工作原理


GPIO的开漏复用输出模式与开漏输出模式的工作原理基本相同

不同的是编号为2 的输入的源不同,它是和复用功能的输出端相连

此时的“输出数据寄存器”被输出通道给断开了。

从上面的这个图,我们还可以看到CPU同样可以从“输入数据寄存器”读取到外部IO端口变化的电平信号。


0
回复
2019-10-24 09:38
@lihui710884923
七、GPIO开漏复用输出_AF_OD模式工作原理[图片]不同的是编号为2的输入的源不同,它是和复用功能的输出端相连从上面的这个图,我们还可以看到CPU同样可以从“输入数据寄存器”读取到外部IO端口变化的电平信号。

八、GPIO推挽复用输出_AF_PP模式工作原理


最后介绍一下GPIO推挽复用输出模式的工作原理

编号2“输出控制电路” 输入是与复用功能的输出端相连

此时“输出数据寄存器”被从输出通道断开了,片上外设的输出信号直接与“输出控制电路”的输入端想连接。

我们将GPIO配置成复用输出功能后,假如相应的外设模块没有被激活,那么此时IO端口的输出将不确定。

其它部分原理与前面叙述的模式一样,包括对“输入数据寄存器”的读取方式也是一样的。


0
回复
2019-10-24 09:40
@lihui710884923
八、GPIO推挽复用输出_AF_PP模式工作原理[图片]编号2“输出控制电路”输入是与复用功能的输出端相连我们将GPIO配置成复用输出功能后,假如相应的外设模块没有被激活,那么此时IO端口的输出将不确定。

4输入 + 2 输出 + 2 复用输出,一共是8种模式

图形结合文字讲解完毕,希望对于stm32单片机新手学习有所帮助

0
回复
2019-11-30 14:41
@lihui710884923
图形结合文字讲解完毕,希望对于stm32单片机新手学习有所帮助
stm32的GPIO讲的很透彻
0
回复
2019-12-07 20:46
@liuxiaofei126
stm32的GPIO讲的很透彻
主要就是对GPIO口的总结
0
回复
2020-07-23 10:32
@lihui710884923
主要就是对GPIO口的总结
这个不错感觉,对于初学者直观明了的介绍了其工作原理,多谢
0
回复
2020-07-24 12:30
@沃默思情
这个不错感觉,对于初学者直观明了的介绍了其工作原理,多谢
没事,图解直观一点
0
回复
2022-03-11 11:34

对于刚入门的新手,我想这几个概念是必须得搞清楚的,平时接触的最多的也就是推挽输出、开漏输出、上拉输入这三种,但一直未曾对这些做过归纳。因此,在这里做一个总结:

推挽输出:可以输出高,低电平,连接数字器件; 推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源低定。

推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小效率高。输出既可以向负载灌电流,也可以从负载抽取电流推拉式输出级既提高电路的负载能力,又提高开关速度。

详细理解:



如图所示,推挽放大器的输出级有两个“臂”(两组放大元件),一个“臂”的电流增加时,另一个“臂”的电流则减小,二者的状态轮流转换。对负载而言,好像是一个“臂”在推,一个“臂”在拉,共同完成电流输出任务。当输出高电平时,也就是下级负载门输入高电平时,输出端的电流将是下级门从本级电源经VT3拉出。这样一来,输出高低电平时,VT3 一路和 VT5 一路将交替工作,从而减低了功耗,提高了每个管的承受能力。又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。因此,推拉式输出级既提高电路的负载能力,又提高开关速度。

开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内).

开漏形式的电路有以下几个特点:

1. 利用外部电路的驱动能力,减少IC内部的驱动。当IC内部MOSFET导通时,驱动电流是从外部的VCC流经R pull-up ,MOSFET到GND。IC内部仅需很下的栅极驱动电流。

2. 一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。上拉电阻的阻值决定了逻辑电平转换的沿的速度 。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度

3. OPEN-DRAIN提供了灵活的输出方式,但是也有其弱点,就是带来上升沿的延时。因为上升沿是通过外接上拉无源电阻对负载充电,所以当电阻选择小时延时就小,但功耗大;反之延时大功耗小。所以如果对延时有要求,则建议用下降沿输出。

4. 可以将多个开漏输出的Pin,连接到一条线上。通过一只上拉电阻,在不增加任何器件的情况下,形成与逻辑关系。这也是I2CSMBus等总线判断总线占用状态的原理。补充:什么是“线与”?:

在一个结点(线), 连接一个上拉电阻到电源 VCC  VDD  n  NPN  NMOS 晶体管的集电极 C 或漏极 D, 这些晶体管的发射极 E 或源极 S 都接到地线上, 只要有一个晶体管饱和, 这个结点(线)就被拉到地线电平上. 因为这些晶体管的基极注入电流(NPN)或栅极加上高电平(NMOS), 晶体管就会饱和, 所以这些基极或栅极对这个结点(线)的关系是或非 NOR 逻辑. 如果这个结点后面加一个反相器, 就是或 OR 逻辑.

其实可以简单的理解为:在所有引脚连在一起时,外接一上拉电阻,如果有一个引脚输出为逻辑0,相当于接地,与之并联的回路“相当于被一根导线短路”,所以外电路逻辑电平便为0,只有都为高电平时,与的结果才为逻辑1。

关于推挽输出和开漏输出,最后用一幅最简单的图形来概括:


该图中左边的便是推挽输出模式,其中比较器输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当比较器输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平。右边的则可以理解为开漏输出形式,需要接上拉。

0
回复