基于个人对STM32的GPIO理解

目录

GPIO的理解

 🎯 STM32的GPIO介绍

GPIO基本结构

STM32的GPIO工作方式

浮空输入模式

浮空输入模式​

上拉输入模式​

下拉输入模式​

模拟输入模式​

开漏输出模式​

开漏复用输出模式​

推挽输出模式​

推挽复用输出模式​

端口初始化相关函数

🎯 总结与分析


GPIO的理解

STM32引脚说明 GPIO是通用输入/输出端口的简称

  • 控制具体的引脚输出高\低电压,实现开关的控制或产生PWM(脉冲宽度调制)
  • 能够实现单独的位设置或位清除
  • 当端口设置为输入模式时,能够检测外部的的输入电平,从而判断外设的状态,并且在输入模式下,GPIO端口具有外部中断和唤醒功能
  • 具有端口复用功能
  • 端口复用的重映射功能
  • 端口的配置具有锁定机制,当配置好GPIO端口后,如果在端口位上执行锁定LOCK操作,可以通过程序锁住配置组合,在下一次复位之前,端口位的配置不会被改变

STM32F403ZET6芯片为144脚芯片,包括7个通用目的的输入/输出口(GPIO)组,分别为GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG,同时每组GPIO口组有16个GPIO口。通常简略称为PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。


 🎯 STM32的GPIO介绍

GPIO基本结构

每个GPIO内部都有这样的一个电路结构,这个结构在本文下面会具体介绍。

每个GPIO内部都有这样的一个电路结构,这个结构在本文下面会具体介绍。

 

  • Vcc:C表示”Circuit”,即电路,指接入电路的电压。

  • Vdd:D表示“Device”,即器件,指器件内部的工作电压。

  • Vss:S表示“Series”,即公共连接,通常指电路公告接地端电压。

  • **保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入。**当引脚电压高于VDD时,上方的二极管导通;当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。

  • P-MOS管和N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。这里的电路会在下面很详细地分析到。

  • **TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号。但是,当GPIO引脚作为ADC采集电压的输入通道时,用其“模拟输入”功能,此时信号不再经过触发器进行TTL电平转换。**ADC外设要采集到的原始的模拟信号。

  • 输出数据寄存器。由P-MOS管和N-MOS管组成的CMOS反相器电路的输入信号,是由GPIO端口的输出数据寄存器GPIOx_ODR提供的,因此通过修改输出数据寄存器的值就可以修改GPIO端口引脚的输出电平。

  • 输入数据寄存器。GPIO端口经过内部的上/下拉电阻,可以分别配置为上拉输入和下拉输入两种模式,然后与肖特基触发器相连接,经过触发器之后,模拟信号变成数字信号。存储在GPIO端口的输入数据寄存器GPIOx_IDR中。通过读取该寄存器就能够了解GIPO端口引脚的电平状态。

  • 复用功能输出。由STM32片上的外设功能引脚所引出的复用功能输出信号和GPIO端口引脚本身的输入数据寄存器都连接到CMOS反相器电路的输入端中,由转换开关进行切换选择。

  • 复用功能输入。将GPIO端口的引脚的信号传输到STM32内置片上的外设,由该外设读取引脚的状态。

  • 模拟输入输出。当GPIO端口用于ADC采集电压的输入通道时,由于经过肖特基触发器后,模拟信号会被转化为数字信号,即只有1、0两种状态,所以为了使ADC采集到原始的模拟信号,信号源的输入必须跳过肖特基触发器,此时需要使用模拟输入,使信号在不经过肖特基触发器的情况下直接输入,当GPIO端口用于DAC作为模拟电压的输出通道时,需要使用模拟输出,从而使DAC的模拟信号不需要经过CMOS反相器电路,直接输出到端口。

STM32的GPIO工作方式

GPIO支持4种输入模式(浮空输入、上拉输入、下拉输入、模拟输入)和4种输出模式(开漏输出、开漏复用输出、推挽输出、推挽复用输出)。同时,GPIO还支持三种最大翻转速度(2MHz、10MHz、50MHz)。

每个I/O口可以自由编程,但I/O口寄存器必须按32位字被访问。

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        复用推挽输出

typedef struct
        {
          uint32_t GPIO_Pin;              /*!< 引脚号 */
          GPIOMode_TypeDef GPIO_Mode;     /*!< 选择模式*/
          GPIOSpeed_TypeDef GPIO_Speed;   /*!< 输出速度*/
          GPIOOType_TypeDef GPIO_OType;   /*!< 类型*/
          GPIOPuPd_TypeDef GPIO_PuPd;     /*!< 上拉和下拉 */
        }GPIO_InitTypeDef;

八种细分的GPIO端口工作模式大致分为三类:

  1. 输入模式(模拟/浮空/下拉/上拉)。当处于输入模式的时候,肖特基触发器打开,GPIO端口输出被禁止,此时可以通过GPIOx_IDR来读取GPIO端口的引脚状态。上拉是电位拉高,下拉是电位拉低。上拉输入是将一个不确定的信号通过内置电阻上拉为高电平进行输入,而下拉输入是将一个不确定的信号通过内置电阻下拉为低电平输入,GPIO端口引脚的电平由上拉或下拉决定。浮空输入的电平是不确定的,完全由外部输入决定,一般连接按键的时候会用浮空。模拟输入主要用于ADC采集。
  2. 输出模式(推挽/开漏)。在推挽输出中,P-MOS管和N-MOS管轮流工作,通过输出数据寄存器GPIOx_ODR可控制端口输出高低电平;在开漏输出模式中,只有N-MOS管工作,通过输出数据寄存器GPIOx_ODR可控制端口输出高低电平,而且端口的输出速率是可以配置的,可选择2MHz、10MHz和50Mhz等。此处的输出速率是指端口支持的高低电平状态的最高切换频率,支持的频率越高,功耗就越大。在输出模式时,肖特基触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可以读取端口的实际状态。
  3. 复用功能(推挽/开漏)。在复用功能模式中,端口输出使能,其输出速率可以配置,能够工作在推挽或者开漏两种模式下,但是此时的输出信号源于其他片外设,输出数据寄存器GPIOx_ODR无效;当端口复用功能的输入可用时,通过GPIOx_IDR可以读取端口的实际状态,但是一般会直接用外设的寄存器获取该数据信号。

    下面将具体介绍GPIO的这八种工作方式:

    浮空输入模式

    下面将具体介绍GPIO的这八种工作方式:

    浮空输入模式

     浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。

    上拉输入模式

     上拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在高电平;并且在I/O端口输入为低电平的时候,输入端的电平也还是低电平。

    下拉输入模式

     下拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也还是高电平。

    模拟输入模式

     模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等。

    开漏输出模式

     开漏输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经**N-MOS管,最终输出到I/O端口。这里要注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。**同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平。

    开漏复用输出模式

     开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。

    推挽输出模式

     推挽输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。这里要注意P-MOS管和N-MOS管,当设置输出的值为高电平的时候,P-MOS管处于开启状态,N-MOS管处于关闭状态,此时I/O端口的电平就由P-MOS管决定:高电平;当设置输出的值为低电平的时候,P-MOS管处于关闭状态,N-MOS管处于开启状态,此时I/O端口的电平就由N-MOS管决定:低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,此时I/O端口的电平一定是输出的电平。

    推挽复用输出模式

     推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。

    端口初始化相关函数

  • void ** GPIO_DeInit **(GPIO_TypeDef *GPIOx)

  • 功能:将GPIOx外设寄存器初始化为默认值 注释:判断GPIOx具体为哪个端口,再通过操作RCC_APB2RSTR(APB2外设复位寄存器)对其寄存器进行复位 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 例:GPIO_DeInit(GPIOA);

  • void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

  • 功能:按照GPIO_InitStruct结构体变量所配置的参数来初始化GPIOx寄存器 注释:将结构体内成员所赋的值取出并赋给对应的寄存器 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 输入参数2:GPIO_InitStruct:指向GPIO_InitTypeDef的指针,包括外设GPIO配置信息 例:GPIO_Init(GPIOA,&GPIO_InitStructure);

    typedef struct
    {
    		u16 GPIO_Pin;
    		GPIOSpeed_TypeDef  
        GPIO_Speed;
    		GPIOMode_TypeDef 
        GPIO_Mode;
    } GPIO_InitTypeDef;
    
    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复用推挽输出

    配置GPIOA端口的引脚2、3为浮空输入,并设置最大工作速率为10MHz

    GPIO_InitTypeDef  GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;  //PA2.PA3引脚设置
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;     //I/O端口速率为10MHz
    GPIO_InitStructure.GPIO.Mode = GPIO_Mode_IN_FLOATING  //工作模式为浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);                //初始化GPIOA寄存器
    
    • GPIO_PIn。它用于选择带配置的GPIO端口,使用操作符“|”能够一次性选择多个引脚

      GPIO_PIn选择说明
      GPIO_PIn_None无引脚选中
      GPIO_PIn_1选中引脚1
      GPIO_PIn_All选择全部的引脚
    • GPIO_Speed。它用于设定GPIO端口的最大工作速度。

    • GPIO_Mode。它用来设置选中引脚的工作状态。

  • void GPIO_AFIODeInit(void)

    功能:将复用功能(重映射与EXTI设置)重设为默认值 注释:通过操作RCC_APB2RSTR(APB2外设复位寄存器)对其寄存器进行复 输入参数:无 例:GPIO_AFIODeInit()

  • void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)

    功能:将GPIO结构体各个成员填充为默认值 注释:未涉及寄存器操作,直接向结构体成员赋默认值

  • void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

    功能:锁定GPIO管脚的配置,下次系统复位之前将不能再更改端口位的配置,一个或多个 注释:根据键写入序列,通过操作LCKK与LCKx来进行设置 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 输入参数2:GPIO_Pin_x:x可以是0~15中的任意一个,待用来选择锁定端口位 例:GPIO_PinLockConfig(GPIOA, GPIO_Pin_0 | GPIO_Pin_1);

  • void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

    功能:设置选定的数据端口位,置“1”,一个或多个 注释:使用GPIOx_BSRR的端口位设置功能来达到设置引脚输出为“1”的目的 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 输入参数2:GPIO_Pin_x:x可以是0~15中的任意一个,待用来选择锁定端口位 例:GPIO_SetBits(GPIOA, GPIO_Pin_10 | GPIO_Pin_15);

  • void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

    功能:清除指定的数据端口位,清“0”,一个或多个 注释:通过操作BRR寄存器来实现端口引脚的低电平输出 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 输入参数2:GPIO_Pin_x:x可以是0~15中的任意一个,待用来选择锁定端口位 例:GPIO_ResetBits(GPIOA, GPIO_Pin_10 | GPIO_Pin_15);

  • void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)

    功能:对某一个端口管脚实现清“0”或置“1”操作 注释:判断电平,进而对应操作BRR或者BSRR 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 输入参数2:GPIO_Pin_x:x可以是0~15中的任意一个,待用来选择锁定端口位 输入参数3:BitVal:指定了待写入的位值是BIT_SET(高电平)还是BIT_RESET(低电平) 例:GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);

  • uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

    功能:读取指定端口引脚的输入电平,针对Pin 注释:通过访问GPIOx_IDR(端口输入数据寄存器)可获知某一引脚的输入电平 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 输入参数2:GPIO_Pin_x:x可以是0~15中的任意一个,待用来选择锁定端口位 例: uint8_t ReadValue; ReadValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7);

  • uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)

    功能:读取指定GPIO端口的输入电平,针对Port 注释:通过访问GPIOx_IDR(端口输入数据寄存器)可获知某一端口的输入电平 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 例: uint16_t ReadValue; ReadValue = GPIO_ReadInputData(GPIOC);

  • uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)

    功能:读取指定GPIO端口的输出电平,针对Port 注释:通过访问GPIOx_ODR(端口输出数据寄存器)可获知某一端口的输出电平 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 例:uint16_t ReadValue; ReadValue = GPIO_ReadOutputData(GPIOC);

  • void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)

    功能:向某一端口写入指定数据 注释:将数据写入GPIOx_ODR寄存器,ODR可读可写,但只能字操作 输入参数1:GPIOx:x可以为A,B,C,D等。用来选择GPIO外设 例:GPIO_Write(GPIOA, 0x1234);

  • void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)

    功能: 选择GPIO管脚用作事件输出 注释:对AFIO_EVCR的操作 输入参数1:GPIO_PortSourceGPIOx:x可以为A,B,C,D等。用来选择GPIO外设 输入参数2:GPIO_PinSourcex:x可以是0~15中的任意一个,待用来选择锁定端口位 例:GPIO_EventOutputConfig(GPIO_PortSourceGPIOE, GPIO_PinSource5);

  • void GPIO_EventOutputCmd(FunctionalState NewState)

    功能:使能或失能事件输出 注释:与GPIO_EventOutputConfig配合使用 输入参数1:NewState:事件输出的新状态(可取ENABLE和DISABLE) 例:GPIO_EventOutputCmd(ENABLE);

  • void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)

    功能:选择GPIO管脚作为中断线路 注释:16个管脚占用了4个寄存器 输入参数1:GPIO_PortSourceGPIOx:x可以为A,B,C,D等。用来选择GPIO外设 输入参数2:GPIO_PinSourcex:x可以是0~15中的任意一个,待用来选择锁定端口位 例:GPIO_EXTILineConfig(GPIO_PortSource_GPIOB, GPIO_PinSource8);

🎯 总结与分析

1、什么是推挽结构和推挽电路?

推挽结构一般是指两个参数相同的三极管或MOS管分别受两互补信号的控制,总是在一个三极管或MOS管导通的时候另一个截止。高低电平由输出电平决定。

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

2、开漏输出和推挽输出的区别?

开漏输出:只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极。适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内); 推挽输出:可以输出强高、低电平,连接数字器件。 关于推挽输出和开漏输出,最后用一幅最简单的图形来概括:

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

3、在STM32中选用怎样选择I/O模式?

  • 浮空输入_IN_FLOATING ——浮空输入,可以做KEY识别,RX1
  • 带上拉输入_IPU——IO内部上拉电阻输入
  • 带下拉输入_IPD—— IO内部下拉电阻输入
  • 模拟输入_AIN ——应用ADC模拟输入,或者低功耗下省电
  • 开漏输出_OUT_OD ——IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能
  • 推挽输出_OUT_PP ——IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的
  • 复用功能的推挽输出_AF_PP ——片内外设功能(I2C的SCL、SDA)
  • 复用功能的开漏输出_AF_OD——片内外设功能(TX1、MOSI、MISO.SCK.SS)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值