一、前言
万物皆有源头,大家学习单片机的源头操作就是通过GPIO口点灯,GPIO作为STM32最基础的外设,也是大家最先接触的外设。当然,看似基础的GPIO,不仅仅是简单的设置好IO口,让灯亮起就一了百了,了解清楚GPIO的使用特性,根本原理、运行机制对我们在涉及到GPIO的相关设计操作上会应用的更加自如。
GPIO就是通用输入/输出接口(General-Purpose IO ports),可以配置成输出模式来控制外部设备,也可以配置成输入模式来读取外部信号,是STM32的一种外设,连接芯片外部的引脚,其引脚可以供使用者自由的进行控制。将STM32芯片的GPIO引脚与外部设备连接起来,也可以实现与外部通讯、控制以及数据采集的功能。GPIO最简单的功能是输出高低电平;GPIO还可以被设置为输入功能,用于读取按键等输入信号;也可以将GPIO复用成芯片上的其他外设的控制引脚。
后续将从以下图1中所示的几个方面对GPIO进行详细的解析。
图1 GPIO学习框架
二、基本结构概述
首先对GPIO的基本结构进行详细分析。了解GPIO的基本结构对GPIO的模块的静态全貌、运行机理、配置使用有很好的帮助,图2为STM32的5V容忍的GPIO口内部基本结构图,图3为GPIO的基本结构中各个模块部分的概述。
图2 STM32的5V容忍的GPIO内部基本结构
图3 GPIO基本结构包含的功能概述
Q:什么是5V容忍?
A:在数字电平的规范中,有很多电压都被设置为逻辑电平,比较典型的有5V,3.3V,2.5V,1.8V,1.2V等等,通常的规律是电路运行的速度越快,使用的逻辑电平电压越低。
而STM32使用的是3.3V的逻辑电平,各个引脚输出与输入的逻辑电平应该是3.3V,ST公司为了增加芯片的兼容性,实现了对5V逻辑电平的容忍,意思是可以正常识别5V的逻辑电平信号而不至于因为逻辑电平电压高于自身的3.3V标准而损坏芯片,这里的容忍就是正常识别不损坏的意思。
图4 STM32芯片手册中GPIO的定义
一般而言能够容忍5V的话都会写有“FT”两个字。因此,并不是所有的I/O都是能容忍5V的。注意:如果引脚设置的是模拟输入模式,则不能接5V!
下图为GPIO引脚电压特性和电流特性的绝对最大额定值。
图5 STM32芯片手册中GPIO的电压电流特性
加在器件上的电压或电流如果超过绝对最大额定值,可能会导致器件永久性地损坏。这里只是给出能承受的最大电压或电流,并不意味在此条件下器件的功能性操作无误,器件长期工作在最大值条件下会影响器件的可靠性。
三、基本结构详述
从图2中可以看出,从右往左为GPIO在芯片内部的连接通路。各个模块描述如下:
(1)保护二极管
引脚上的这两个保护二极管可以将引脚外部过高或过低的电压进行钳位,当引脚电压高于VDD_FT 或VDD 时,上方的二极管导通吸收这个高电压,当引脚电压低于VSS 时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。水平的检测管脚Pin是受保护的节点。当该点电压超过VDD+VD1(0.7V)时,上面的二极管导通。而当该点电压小于-VD2(-0.7V)时,下面的二极管导通。因此,该点电压被钳制在VDD+VD1到-VD2间。
尽管STM32 芯片内部有这样的保护,但并不意味着STM32 的引脚就无所不能,从之前的电流特性表中可知,IO口的电流很小,如果直接将引脚连接大功率器件,比如电机,那么要么电机不转,要么烧坏芯片。因此若要驱动一些大功率器件,必须要加大功率及隔离电路驱动。也可以说STM32引脚是用来做控制,而不是做驱动使用的。
图6 钳位二极管图
(2)上下拉电阻
上拉和下拉电阻上都有一个开关,通过配置上下拉电阻开关,可以控制引脚的默认状态电平。当开启上拉时引脚默认电压为高电平,开启下拉时,引脚默认电压为低电平,这样就可以消除引脚不定状态的影响。当然也可以将上拉和下拉的开关都关断,这种状态我们称为浮空模式,一旦配置成这个模式,引脚的电压是不确定的,如果用万用表测量此模式下管脚电压时会发现只有1 点几伏,而且还不时改变,所以一般情况下我们都会给引脚设置成上拉或者下拉模式,使它有一个默认状态。STM32 上下拉及浮空模式的配置是通过GPIOx_CRL 和GPIOx_CRH 寄存器控制的。STM32 内部的上拉其实是一个弱上拉,也就是说通过此上拉电阻输出的电流很小,如果想要输出一个大电流,那么就需要外接上拉电阻了。
图7 上下拉电阻图
下图可以知晓STM32芯片的GPIO口上下拉电阻的最小值,典型值和最大值。
图8 STM32芯片手册给定的GPIO上下拉电阻值
(3)P-MOS 和N-MOS 管
图2中GPIO 引脚经过两个保护二极管后就分成两路,上面一路是经过输入驱动器为“输入模式”,下面一路经过输出驱动器为“输出模式”。
当为输出模式时,线路经过输出控制缓冲器到一个由P-MOS 和N-MOS管组成的双MOS电路,因此GPIO 引脚可以配置成推挽和开漏两种输出模式。
图9 双MOS电路图
推挽输出模式,是根据P-MOS 和N-MOS 管的工作方式命名的。在该结构单元输入一个高电平时,P-MOS 管导通,N-MOS 管截止(可以将P-MOS 看作NPN三极管,N-MOS看作PNP 三极管),对外输出高电平(3.3V)。在该单元输入一个低电平时,P-MOS 管截止,N-MOS 管导通,对外输出低电平(0V)。如果当切换输入高低电平时,两个MOS 管将轮流导通,一个负责灌电流(电流输出到负载),一个负责拉电流(负载电流流向芯片),使其负载能力和开关速度都比普通的方式有很大的提高。
图10 推挽输出
开漏输出模式时,不论输入是高电平还是低电平,P-MOS 管总处于关闭状态。当给这个单元电路输入低电平时,N-MOS 管导通,输出即为低电平。当输入高电平时,N-MOS 管截止,这个时候引脚状态既不是高电平,又不是低电平,我们称之为高阻态。如果想让引脚输出高电平,那么引脚必须外接一个上拉电阻,由上拉电阻提供高电平。开漏输出模式等效电路图如图所示。
图11 开漏输出
在开漏输出模式中还有一个特点,引脚具有“线与”关系。就是说如果有很多个开漏输出模式的引脚接在一起,只要有一个引脚为低电平,其他所有管脚都为低,即把所有引脚连接在一起的这条总线拉低了。只有当所有引脚输出高阻态时这条总线的电平才由上拉电阻的VDD 决定。如果VDD 连接的是3.3V,那么引脚输出的就是3.3V,如果VDD 连接的是5V,那么引脚输出的就是5V。因此如果想要让STM32 管脚输出5V,可以选择开漏输出模式,然后在外接上拉电阻的电源VDD 上连接5V 即可,前提是这个STM32引脚是容忍5V的。
开漏输出模式一般应用在I2C、SMBUS 通讯等需要“线与”功能的总线电路中。还可以用在电平不匹配的场合中,就如上面说的输出5V 一样。推挽输出模式一般应用在输出电平为0-3.3V 而且需要高速切换开关状态的场合。除了必须要用开漏输出模式的场合,我们一般选择推挽输出模式。要配置引脚是开漏输出还是推挽输出模式可以使用GPIOx_CRL 和GPIOx_CRH 寄存器。
(4)输出数据寄存器
前面提到的双MOS 管结构电路的输入信号,由GPIO“输出数据寄存器GPIOx_ODR”提供,因此通过修改图12中输出数据寄存器的值就可以修改GPIO 引脚的输出电平,同时“输出数据寄存器GPIOx_ODR”的数值状态也是可读的。
而如果需要对输出电平信号进行原子操作,可以通过图12中“置位/复位寄存器GPIOx_BSRR”修改输出数据寄存器的值从而改变GPIO的输出。该寄存器是只写寄存器,通过写入 “置位/复位寄存器GPIOx_BSRR”状态,可分别对 “输出数据寄存器GPIOx_ODR” 进行置位和复位。
刚开始或许你跟我一样有以下疑惑:既然ODR 能控制管脚高低电平,为什么还需要BSRR寄存器?
意法半导体给的答案就是用BSRR去改变管脚状态的时候是原子操作置位/复位,没有被中断打断的风险。也就不需要关闭中断,关闭中断明显会延迟或丢失一事件的捕获,所以控制GPIO的状态最好可以用BSRR。
图12 输出数据寄存器部分图
(5)复用功能输出
STM32 的GPIO 引脚不仅仅可以用作普通IO输出电平进行控制,还可以用作芯片上其他外设的复用功能引脚。因此当使用复用功能的时候,也就是其他外设复用功能输出信号将直接经过图12中输出控制缓冲器后,作为双MOS 管电路的输入,其中信号在进入输出控制缓冲器之前,需要选择使用复用功能还是普通IO 口功能。例如,我们使用USART 串口通讯时,需要用到某个GPIO 引脚作为通讯发送引脚,这个时候就可以把该GPIO 引脚配置成USART 串口复用功能,由芯片上的串口外设控制该引脚,发送数据。具体使用的GPIO口具备哪些复用功能,可以查阅具体的芯片手册得到。
图13 STM32芯片手册中GPIO复用功能定义
(6)输入数据寄存器
输入数据寄存器是由IO口经过上下拉电阻、TTL施密特触发器引入。当信号经过TTL施密特触发器,模拟信号将变为数字信号0 或1,然后存储在输入数据寄存器中,通过读取“输入数据寄存器GPIOx_IDR” 就可以知道IO 口的电平状态。
施密特触发器:简单来说,就是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;当输入在正负向阈值电压之间,输出不改变。因此只有当输入电压发生足够的变化时,输出才会变化,因此将这种元件命名为触发器。这种双阈值动作被称为迟滞现象,表明施密特触发器有记忆性。从本质上来说,施密特触发器是一种双稳态多谐振荡器。
施密特触发器可作为波形整形电路,能将模拟信号波形整形为数字电路能够处理的方波波形,而且由于施密特触发器具有滞回特性,所以可用于抗干扰。
图14 输入数据寄存器部分图
(7)复用功能输入
复用功能输入和复用功能输出类似。在复用功能输入模式时,GPIO 引脚的信号传输到STM32芯片上 其它外设,由该外设读取引脚的状态。同样,如我们使用USART 串口通讯时,需要用到某个GPIO 引脚作为通讯接收引脚,这个时候就可以把该GPIO 引脚配置成USART 串口复用功能,使USART 可以通过该通讯引脚的接收外部通信线上的数据。
(8)模拟输入输出
当GPIO 引脚用于ADC 采集电压的输入通道时,用作“模拟输入”功能,如图14所示,此时信号是不经过施密特触发器的,因为经过施密特触发器后信号只有0或1 两种状态,ADC 外设要采集到原始的模拟信号,信号源输入必须在施密特触发器之前。类似地,当GPIO 引脚用于DAC 作为模拟电压输出通道时,此时作为“模拟输出”功能,如图12所示,DAC 的模拟信号输出就不经过双MOS 管结构了,模拟信号直接通过管脚输出。
四、总结
以上针对STM32芯片的GPIO基本结构中各个模块的原理和作用分别进行了介绍,可以对GPIO的静态全貌有一个初步的了解,在下一篇将继续介绍GPIO基础知识篇之工作模式。
更多技术内容和书籍资料获取,入群技术交流敬请关注公众号“明解嵌入式”