一、前言
万物皆有源头,大家学习单片机的源头操作就是通过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标准而损坏芯片,这里的容忍就是正常识别不损坏的意思。
一般而言能够容忍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引脚是用来做控制,而不是做驱动使用的。
(2)上下拉电阻
上拉和下拉电阻上都有一个开关,通过配置上下拉电阻开关,可以控制引脚的默认状态电平。当开启上拉时引脚默认电压为高电平,开启下拉时,引脚默认电压为低电平,这样就可以消除引脚不定状态的影响。当然也可以将上拉和下拉的开关都关断,这种状态我们称为浮空模式,一旦配置成这个模式,引脚的电压是不确定的,如果用万用表测量此模式下管脚电压时会发现只有1 点几伏,而且还不时改变,所以一般情况下我们都会给引脚设置成上拉或者下拉模式,使它有一个默认状态。STM32 上下拉及浮空模式的配置是通过GPIOx_CRL 和GPIOx_CRH 寄存器控制的。STM32 内部的上拉其实是一个弱上拉,也就是说通过此上拉电阻输出的电流很小,如果想要输出一个大电流,那么就需要外接上拉电阻了。
下图可以知晓STM32芯片的GPIO口上下拉电阻的最小值,典型值和最大值。
(3)P-MOS 和N-MOS 管
图2中GPIO 引脚经过两个保护二极管后就分成两路,上面一路是经过输入驱动器为“输入模式”,下面一路经过输出驱动器为“输出模式”。
当为输出模式时,线路经过输出控制缓冲器到一个由P-MOS 和N-MOS管组成的双MOS电路,因此GPIO 引脚可以配置成推挽和开漏两种输出模式。
推挽输出模式,是根据P-MOS 和N-MOS 管的工作方式命名的。在该结构单元输