STM32 GPIO

STM32 GPIO

GPIO简介

  • GPIO(General Purpose Input Output)通用输入输出口,也就是我们俗称的IO口

  • 根据使用场景,可配置为8种输入输出模式

  • 引脚电平:0V~3.3V,部分引脚可容忍5V

    • 数据0就是低电平,也就是0V;数据1就是高电平,也就是3.3V。
    • 容忍5V的意思是可以在这个端口输入5V的电压,也认为是高电平,但是对于输出而言,最大就只能输出3.3V,因为供电就只有3.3V。
      • 具体哪些引脚可以容忍5V,见引脚定义表I/O口电平一列带FT(Five Tolerate)的就是可以容忍5V的,不带FT的就只能接入3.3V的电压。
  • 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序(I2C,SPI或者某个芯片特定的协议)等

    • 在其他场景,只要是可以用高低电平来进行控制的地方,都可以用GPIO来完成,如果控制的是功率比较大的设备,只需要再假如驱动电路即可。
  • 输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

    • 输入模式最常见的就是读取按键,用来捕获我们的按键按下事件。
    • 另外也可以读取带有数字输出的一些模块,比如光敏电阻模块,热敏电阻模块。
    • 如果这个模块输出的是模拟量,那GPIO还可以配置成模拟输入模式,再配合内部的ADC外设,就能直接读取端口的模拟电压。
    • 模拟通信协议时,接受通信线上的数据,也是靠GPIO的输入来完成的。

GPIO基本结构

  • APB2外设总线,所有的GPIO都是挂载在APB2外设总线上的。
  • GPIO外设的名称是按照GPIOA、GPIOB、GPIOC等等这样来命名的,每个GPIO外设,总共有16个引脚,编号是从0~15,那GPIO的第0号引脚,我们一般把它称作PA0,接着第1号引脚就是PA1,然后PA2,以此类推,一直到PA15,GPIOB也是如此,从PB0~PB15这样来命名。
  • 在每隔GPIO模块内,主要包含了寄存器和驱动器这些东西。
    • 寄存器就是一段特殊的存储器,内核可以通过APB2总线对寄存器进行读写,这样就可以完成输出电平和读取电平的功能了。
      • 这个寄存器的每一位对应一个引脚
        • 输出寄存器写1,对应的引脚就会输出高电平,写0,就输出低电平。
        • 输入寄存器读取为1,就证明对应的端口目前是高电平,读取为0,就是低电平。
        • 因为STM32是32位的单片机,所以STM32内部的寄存器都是32位的。但这个端口只有16位,所以这个寄存器只有低16位有对应的端口,高16位是没有用到的。
    • 这个驱动器是用来增加信号的驱动能力的,寄存器只负责存储数据,如果要进行点灯这样的操作的话,还是需要驱动器来负责增大驱动能力。

STM32 GPIO_第1张图片

GPIO位结构

  • 三个寄存器

    • 位设置/清除寄存器
    • 输出数据寄存器
    • 输入数据寄存器
  • 两个驱动器

    • 输入驱动器
    • 输出驱动器
  • I/O引脚

  • 输入部分

    • 输入信号首先是通过I/O引脚进来,这里接了两个保护二极管,是对输入电压进行限幅的。上面这个二极管接VDD,3.3V,下面接VSS,0V。
      • 如果输入电压比3.3V还要高,那上方这个二极管就会导通,输入电压产生的电流就会直接流入VDD而不会流入内部电路,这样就可以避免过高的电压对内部这些电路产生伤害。
      • 如果输入电压比0V还要低,这个电压是相对VSS的电压,所以是可以有负电压的,那这时下方这个二极管就会导通,电流会从VSS直接流出去,而不会从内部电路汲取电流,也是可以保护内部电路的。
      • 如果输入电压在0~3.3V之间,那两个二极管均不会导通,这时二极管对电路没有影响,这就是保护二极管的用途。
    • 接下来输入信号向上,这里连接了一个上拉电阻和一个下拉电阻,上拉电阻是VDD,下拉电阻是VSS,这个开关可以通过程序进行配置。
      • 如果上面导通、下面断开,就是上拉输入模式;如果下面导通、上面断开,就是上拉输入模式,如果两个都断开,就是浮空输入模式。
      • 上拉电阻和下拉电阻其实是为了给输入提供一个默认的输入电平的,因为对于一个数字的端口,输入不是高电平就是低电平。如果输入引脚什么都不接,就无法判断此刻是高点平还是低电平,这时输入就会处于一种浮空的状态,引脚的输入电平极易守外界干扰而改变。为了避免引脚悬空导致的输入数据不确定,我们就需要在这里加上上拉电阻或者下拉电阻。
        • 如果接入上拉电阻,当引脚悬空时,还有上拉电阻来保证引脚的高电平,所以上拉输入又可以称作是默认为高电平的输入模式。
        • 下拉输入也是同理,就是默认为低电平的输入方式。
      • 这个上拉电阻和下拉电阻的阻值都是比较大的,是一种弱上拉和弱下拉,目的是尽量不影响正常的输入操作。
    • 接下来,信号通过施密特触发器(TTL肖基特触发器),这个施密特触发器的作用就是对输入电压进行整形。
      • 它的执行逻辑是
        • 如果输入电压大于某一阈值,输出就会瞬间升为高电平。
        • 如果输入电压小于某一阈值,输出就会瞬间降为低电平。
    • 举个例子,因为这个引脚的波形是外界输入的,虽然是数字信号,实际情况下可能会产生各种失真,比如一个夹杂了波动的高低变化电平信号,如果没有施密特触发器,那很有可能因为干扰而导致误判,如果有了施密特触发器,确定一个阈值上限和下限,高于上限输出高电平,低于下限输出低电平 。对于施密特触发器来说,只有高于上限或者低于下限,输出才会变化,即使信号在下限附近来回横跳,因为没有达到阈值上限,所以一直会输出低电平,知道高于上限,才会输出高电平。
    • 使用两个比较阈值来进行判断,中间留有一定的变化范围,可以有效地避免因信号波动造成的输出抖动现象。
    • 经过施密特触发器整形的波形就可以直接写入输入数据寄存器了,再用程序读取输入数据寄存器某一位的数据,就可以知道端口的输入电平了。
    • 模拟输入/复用功能输入(至片上外设),就是连接到片上外设的一些端口
      • 模拟输入,连接到ADC上,因为ADC需要接收模拟量,所以与之相连的这根线是接在施密特触发器之前的。
      • 复用功能输入,连接到其他需要读取端口的外设上,比如串口的输入引脚等,与之相连的这根线接收的是数字量,所以接在施密特触发器之后。
  • 输出部分

    • 数字部分可以由输出数据寄存器或片上外设控制,两种控制方式通过数据选择器接到了输出控制部分。
      • 通过输出数据寄存器进行控制,就是普通的IO口输出,写这个数据寄存器的某一位就可以操作对应的某个端口了。
        • 位设置/清除寄存器可以用来单独操作输出数据寄存器的某一位,而不影响其他位。
        • 因为这个输出数据寄存器同时控制16个端口,并且这个寄存器只能整体读写,所以如果想单独控制其中某一个端口而不影响其他端口的话,就需要一些特殊的操作方式。
          • 第一种方式是先读出这个寄存器,然后用按位与和按位或的方式更改某一位,最后再将更改后的数据写回去,在C语言中就是&=和|=的操作。这种方法比较麻烦,效率不高,对于IO口的操作而言不太合适。
          • 第二种方式是通过设置这个位设置/清除寄存器。
            • 如果我们要对某一位进行置1操作,在位设置寄存器的对应位写1即可,剩下不需要操作的位写0,这样内部就会有电路,自动将输出数据寄存器中对应位置为1,而剩下写0的位则保持不变,这样就保证了只操作其中某一位而不影响其他位,并且这是一步到位的操作。
            • 如果想对某一位进行清0的操作,就在位清除寄存器的对应位写1即可,这样内部电路就会把这一位清零了。
          • 第三种方式就是读写STM32中的“位带”区域,“位带”区域,专门分配的有一段地址区域,这段地址影射了RAM和外设寄存器所有的位,读写这段地址中的数据,就相当于读写所映射位置的某一位。
      • 输出控制之后接到了两个MOS管,上面是P-MOS,下面是N-MOS,MOS管就是一种电子开关,我们的信号来控制开关的导通和关闭,开关负责将IO口接到VDD或者VSS。在这里可以选择推挽、开漏或关闭三种输出方式。
        • 在推挽输出下,P-MOS和N-MOS均有效,数据寄存器为1时,上管导通,下管断开,输出直接到VDD,输出高电平;数据寄存器为0时,上管断开,下管导通,输出直接到VSS,就是输出低电平。这种模式下,高低电平均具有比较强的驱动能力,所以推挽输出模式也可以教强推输出模式。
          • 在推挽输出模式下,STM32对IO口具有绝对的控制权,输出高低电平由STM32控制。
        • 在开漏输出模式下,P-MOS无效,N-MOS有效,数据寄存器为1时,下管断开,这时输出相当于断开,也就是高阻态;数据寄存器为0时,下管导通,输出直接接到VSS,输出低电平。
          • 开漏模式下,只有低电平有驱动能力,高电平是没有驱动能力的(外接电源)。
          • 开漏模式可以作为通信协议的驱动方式,比如I2C通信的引脚,就是使用的开漏模式。在多机通信的情况下,这个模式可以避免各个设备的相互干扰。
          • 开漏模式还可以用于输出5V的电平信号,比如在IO口外界一个上拉电阻到5V的电源,当输出低电平时,由内部的N-MOS直接接VSS,当输出高电平时,由外部的上拉电阻拉高至5V,这样就可以输出5V的电平信号,用于兼容一些5V电平的设备。
        • 关闭模式,就是当引脚配置为输入模式的时候,这两个MOS管都无效,也就是输出关闭,端口的电平由外部信号来控制。

STM32 GPIO_第2张图片

GPIO模式

  • 通过配置GPIO的端口配置寄存器,端口可以配置成以下8种模式
  • 除了模拟输入这个模式会关闭数字的输入功能,在其他7个模式中,所有的输入都是有效的。
模式名称 性质 特征
浮空输入 数字输入 可读取引脚电平,若引脚悬空,则电平不确定 (在使用浮空输入时,端口一定要接上一个连续的驱动源,不能出现悬空的状态)
上拉输入 数字输入 可读取引脚电平,内部连接上拉电阻,悬空时默认高电平
下拉输入 数字输入 可读取引脚电平,内部连接下拉电阻,悬空时默认低电平
模拟输入 模拟输入 GPIO无效,引脚直接接入内部ADC (ADC模数转换器的专属配置)
开漏输出 数字输出 可输出引脚电平,高电平为高阻态,低电平接VSS (开漏输出的高电平呈现高阻态,没有驱动能力)
推挽输出 数字输出 可输出引脚电平,高电平接VDD,低电平接VSS (推挽输出的高低电平都是有驱动能力的)
复用开漏输出 (由片上外设控制) 数字输出 由片上外设控制,高电平为高阻态,低电平接VSS
复用推挽输出 (由片上外设控制) 数字输出 由片上外设控制,高电平接VDD,低电平接VSS

浮空/上拉/下拉输入

  • 在输入模式下,输出驱动器是断开的,端口只能输入而不能输出。
  • 上面这两个电阻可以选择为上拉工作、下拉工作或者都不工作,对应的就是上拉输入、下拉输入和浮空输入。
  • 然后输入通过施密特触发器进行波形整形后,连接到输入数据寄存器。
  • 另外右边这个保护二极管这里,上面写的是VDD或VDD_FT,这就是3.3V端口和容忍5V端口的区别。
    • VDD_FT对5V容忍IO脚是特殊的,它与VDD不同。容忍5V的引脚,它的上边保护二极管需要做一下处理,要不然直接接VDD3.3V的话,外部再接入5V电压就会导致上边二极管开启,并且产生比较大的电流,这个是不太妥当的。

STM32 GPIO_第3张图片

模拟输入

  • 输出断开,输入的施密特触发器也是关闭的无效状态。只剩下一根线,就是从引脚直接接入片上外设,也就是ADC,所以当我们使用ADC的时候,将引脚配置为模拟输入就行了,其他时候一般用不到模拟输入。

STM32 GPIO_第4张图片

开漏/推挽输出

  • 输出是由输出数据寄存器控制的,这个P-MOS如果无效,就是开漏输出,如果P-MOS和N-MOS都有效,就是推挽输出。
  • 在输出模式下,输入模式也是有效的,但是在输入模式下,输出都是无效的。即输出模式的时候,也可以读取到输出引脚的电平。
    • 这是因为一个端口只能有一个输出,但可以有多个输入,所以当配置成输出模式的时候,内部也可以顺便输入一下,这个也是没什么问题。

STM32 GPIO_第5张图片

复用开漏/推挽输出

  • 没有连接到输出数据寄存器,引脚的控制权转移到了片上外设,由片上外设来控制,在输入部分,片上外设也可以读取引脚的电平,同时普通的输入也是有效的,顺便接收一下电平信号。

STM32 GPIO_第6张图片

你可能感兴趣的:(stm32,单片机,嵌入式硬件,硬件工程)