目录
[⑤输出部分 输出数据寄存器](#⑤输出部分 输出数据寄存器)
GPIO简介
GPIO(General Purpose Input Output)通用输入输出口,俗称IO口
可配置为8种输入输出模式
**引脚电平:**0V~3.3V,部分引脚可容忍5V(意为,可以在这个端口输入5V的电压,也认为是高电平,但对于输出而言,最大只能输出3.3V,因为供电就只有3.3V,可容忍5V的可参考引脚定义中带有FT的)
输出模式下可控制端口输出高低电平,用于驱动LED、控制蜂鸣器、模拟通信协议输出时序等(在其他的应用场景,只要是可以用高低电平来进行控制地方,都可以用GPIO来完成;如果控制的是功率比较大的设备,只需要再加入驱动电路即可)(模拟通信协议->如I2C、SPI或者某个芯片特定的协议,都可以用GPIO的输出模式来模拟其中的输出时序部分)
输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接受数据等
(最常见可捕获按键按下事件,另外也可以读取带有数字输出的一些模块,比如光敏电阻模块、热敏电阻模块等;如果该模块输出的是模拟量,GPIO还可以配置成模拟输入的模式,再配合内部的ADC外设,就能直接读取端口的模拟电压)
GPIO基本结构
|----------------------------------------------------------------------------|
| |
左边为APB2外设总线
GPIO外设的名称是按照GPIOA、GPIOB、GPIOC等来命名的
每个GPIO外设,总共有16个引脚,编号是从0到15(PA0~PA15、PB0~PB15)
在每个GPIO模块内,主要包含了寄存器和驱动器这些东西;
驱动器是用来增加信号的驱动能力的,寄存器只负责存储数据
寄存器,就是一段特殊的存储器,内核可以通过APB2总线对寄存器进行读写,这样就可以完成输出电平和读取电平的功能。
寄存器 的每一位对应一个引脚:
输出 寄存器写1 ,对应的引脚就会输出高电平
输出 寄存器写0 ,对应的引脚就会输出低电平
输入 寄存器读取为1 ,证明对应的端口目前是高电平
输入 寄存器读取为0 ,证明对应的端口目前为低电平
(高电平都对应1,低电平都对应0)
STM32为32位单片机 ,所以STM32内部的寄存器都是32位的;但该端口只有16位,所以该寄存器只有低16位有对应的端口,高16位是没有用到的;
GPIO位结构
|-----------------------------------------------------------------------------------|
| 原图 |
| 分解 |
整体结构 :
可以分为两个部分
①输入部分(上)
②输出部分(下)
硬件部分结构:
①寄存器
②驱动器
③某IO口的引脚
结构解析
①保护二极管
|----------------------------------------------------------------------------|
| |
作用:对输入电压进行限幅;
电压:上接VDD,为3.3V;下接VSS,为0V;
▷ 若 输入电压比3.3V高 ,上方二极管导通**(I/O->VDD)** ,输入电压产生的电流会直接流入VDD而不会流入内部电路,这样可避免过高电压对内部电路的伤害
▷ 若 输入电压比0V低 (可为负),下方二极管导通**(VSS->I/O)** ,电流会从VSS直接流出去,而不会从内部电路汲取电流,也可以保护内部电路
▷ 如果 输入电压在0~3.3V之间 ,两个二极管均不会导通,这时二极管对电路没影响
这为保护二极管的用途
②上下拉电阻
上拉电阻至VDD,下拉电阻至VSS,这个开关可以通过程序进行配置
|----------------------------------------------------------------------------|
| |
上下拉电阻模式:
▷上面导通,下面断开,为上拉输入模式
▷下面导通,上面断开,为下拉输入模式
▷两个都断开,为浮空输入模式
上下拉的作用:
为了给输入提供一个默认的输入电平(对于数字端口,非高电平即低电平,但若输入引脚什么都不接,难以判断电平状态)
实际输入什么都不接的话,输入会处于一种浮空的状态,引脚的输入电平极易受外界干扰而改变,而为了避免这种引脚悬空导致的输入数据不确定,就需要在这里加上上拉或者下拉电阻
模式与电平:
若接入上拉电阻,引脚悬空时,上拉电阻来保证引脚的高电平,所以上拉输入又可称作默认为高电平的输入模式
下拉同理,为默认为低电平的输入方式
这里上下拉的阻值都比较大,为弱上拉和弱下拉,目的是尽量不影响正常的输入操作
③模拟输入&复用功能输入
连接片上外设的一些端口
|----------------------------------------------------------------------------|
| |
模拟输入:
连接到ADC上的,因为ADC需要接收模拟量,所以那根线时接在施密特触发器前面的
复用功能输入:
连接到其他需要读取的端口的外设上,如串口的输入引脚,这根线接收的是数字量,所以在施密特触发器后面
④施密特触发器
肖特基触发器(×),应为施密特触发器
|----------------------------------------------------------------------------|
| |
作用:对输入电压进行整形
执行逻辑:
如果输入电压大于某一阈值,输出就会瞬间升为高电平;如果输入电压小于某一阈值,输出就会瞬间降为低电平
|-----------------------------------------------------------------------------|
| |
使用两个比较阈值来进行判断,中间留有一定的变化范围,可以有效地避免因信号波动造成的输出抖动现象
⑤输出部分 输出数据寄存器
|----------------------------------------------------------------------------|
| |
输出部分:
数字部分可以由输出数据寄存器或片上外设控制
|----------------------------------------------------------------------------|
| |
两种控制方式通过这个数据选择器接到了输出控制部分
如果选择通过输出数据寄存器进行控制,就是普通的IO口输出,写数据寄存器的某一位就可以操作对应的某个端口了
⑥位设置/清除寄存器
|----------------------------------------------------------------------------|
| |
位设置/清除寄存器作用:
可以用来单独操作输出数据寄存器的某一位,而不影响其他位;因为输出数据寄存器同时控制16个端口,并且该寄存器只能整体读写,所以如果想单独控制其中某个端口而不影响其他端口的话,就需要一些特殊的操作方式
第一种方式:先读出这个寄存器,然后用按位与和按位或的方式更改某一位,最后再将更改后的数据写回去,在C语言中就是 &= 和 |=的操作(麻烦、效率不高、对于IO口的操作而言不太合适)
第二种方式:通过设置 位设置和位清除寄存器,如果对某一位进行置1,在位设置寄存器的对应位写1即可,剩下不需要操作的位写0,这样内部就会有电路,自动将输出数据寄存器中对应位置为1,而剩下写0位则保持不变,这样就保证了只操作其中某一位而不影响其他位,并且这是一步到位的操作
如果想对某一位进行清0 的操作,就在位清除寄存器的对应位写1即可
第三种方式:读写STM32中的"位带"区域,位带的作用跟51单片机的位寻址作用差不多,在STM32中,专门分配的有一段地址区域,这段地址映射了RAM的外设寄存器所有的位,读写这段地址中的数据,就相当于读写所映射位置的某一位,这就是位带的操作方式
⑦MOS管
|----------------------------------------------------------------------------|
| |
P-MOS(上)& N-MOS(下)
MOS管:一种电子开关
信号来控制开关的导通和关闭,开关负责将IO口接到VDD或者VSS;
在这里可以选择 推挽、开漏或关闭 三种输出方式:
1)推免输出模式
在推挽输出模式下,P-MOS和N-MOS均有效;
数据寄存器为1时,上管道通,下管断开,输出直接接到VDD,就是输出高电平;
数据寄存器为0时,上官断开,下管导通,输出直接接到VSS,就是输出低电平;
这种模式下,高低电平均有较强的驱动能力,所以推挽输出模式也可以叫强推输出模式
在推挽输出模式下,STM32对IO口具有绝对的控制权,高低电平都由STM32说的算
2)开漏输出模式
在开漏输出模式下,P-MOS是无效的,只有N-MOS在工作;
数据寄存器为1时,下管断开,这时输出相当于断开,也就是高阻模式;
数据寄存器为0时,下管导通,输出直接接到VSS,也就是输出低电平;
这种模式下,只有低电平有驱动能力,高电平是没有驱动能力的;
该开漏模式可以作为通信协议的驱动方式,比如I2C通信的引脚,就是使用的开漏模式(在多机通信的情况下,这个模式可以避免各个设备的相互干扰);
还可以用于输出5V的电平信号,比如在IO口外接一个上拉电阻到5V的电源,当输出低电平时,由内部的N-MOS直接接VSS,当输出高电平时,由外部的上拉电阻拉高至5V,这样就可以输出5V的电平信号,用于兼容一些5V电平的设备
3)关闭模式
关闭模式,当引脚配置为输入模式的时候,两个MOS管都无效,也就是输出关闭,端口的电平由外部信号来控制
GPIO模式(8种模式)
通过配置GPIO口配置寄存器,端口可以配置成以下8种模式:
位结构的电路会根据我们的配置进行改变,比如开关的通断、N-MOS和P-MOS是否有效、数据选择器的选择等
|----------------------------------------------------------------------------|
| |
浮空输入&上拉输入&下拉输入
这三个模式的电路结构基本是一样的,区别就是上拉电阻和下拉电阻的连接;
它们都属于数字的输入口,特征是都可以读取端口的高低电平;
当引脚悬空时,上拉输入默认是高电平,下拉输入默认是低电平,而浮空输入的电平是不确定的,所以在使用浮空输入时,端口一定要接上一个连续的驱动源,不能出现悬空的状态
|----------------------------------------------------------------------------|
| |
1)在输入模式下,输出驱动器是断开的,端口只能输入而不能输出
2)上面这两个电阻可以选择为上拉工作、下拉工作或者都不工作,对应为上拉输入、下拉输入和浮空输入
3)输入通过施密特触发器进行波形整形后,连接到输入数据寄存器
4)输入保护二极管,上面写的是VDD或者VDD_FT,二者是3.3V端口和容忍5V端口的区别,VDD_FT对5V容忍I/O脚是特殊的,与VDD不同(容忍5V的引脚,它的上边保护二极管要做一下处理,不然这里直接接VDD 3.3V的话,外部再接5V电压就会导致上边二极管开启,即I/O->VDD,并且产生比较大的电流,这样不太妥当 )
模拟输入
特征:GPIO无效,引脚直接接入内部ADC;模拟 输入
|----------------------------------------------------------------------------|
| |
1)输出是断开的,输入的施密特发生器也是关闭的无效状态,所以整个GPIO的这些都是没用的
2)只剩从引脚直接接入片上外设,也就是ADC;所以使用ADC的时候,将引脚配置为模拟输入就行,其他时候一般用不到模拟输入
开漏输出&推挽输出
这两个电路结构也基本一样,都是数字输出端口,可以用于输出高低电平,区别是开漏输出的高电平呈现的是高阻态,没有驱动能力,而推挽输出的高低电平都是具有驱动能力的
|----------------------------------------------------------------------------|
| |
1)输出是由输出数据寄存器控制的
2)P-MOS如果无效,就是开漏输出;如果P-MOS 和 N-MOS 都有效,就是推挽输出
3)在输出模式下,输入模式也是有效的(上俩图,在输入模式下,输出都是无效的,这是因为一个端口只能有一个输出,但可以有多个输入,所以当配置成输出模式的时候,内部也是可以顺便输入一下,没什么影响)
复用开漏输出&复用推挽输出
跟普通的开漏输出和推挽输出差不多,只不过为复用的输出,引脚电平是由片上外设控制的
|----------------------------------------------------------------------------|
| |
1)通用的输出是没有连接的
2)引脚的控制权转移到了片上外设,由片上外设来控制
3)在输入部分,片上外设也可以读取引脚的电平;同时普通的输入也是有效的,顺便接收一下电平信号
4)GPIO 8种模式中,除了模拟输入会关闭数字的输入功能,在其他7个模式中,所有的输入都是有效的
其余可看手册
如外设的GPIO配置,如GPIO寄存器描述(详略如下)
GPIO寄存器描述
|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| | |
GPIO配置寄存器,每个端口的模式由4位进行配置,16个端口就需要64位,所以这里的配置寄存器有两个,一个是端口配置低寄存器,一个是端口配置高寄存器;
|----------------------------------------------------------------------------|
| |
还有GPIO输出的速度 可配置,可限制输出引脚的最大翻转速度,设计出来是为了低功耗和稳定性的,一般要求不高时配置成50MHz就可以了
|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| | |
端口输入数据寄存器,就是施密特触发器后的那个输入数据寄存器;里面低16位对应16个引脚,高16位没有使用
|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| | |
端口输出数据寄存器,也就是如图二的寄存器;同样,低16位对应16个引脚,高16位没有使用
|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| | |
端口位设置/清除寄存器,如图二;这个寄存器的高16位是进行位清除的,低16位是进行位设置的,写1就是设置或清除,写0就是不产生影响
|----------------------------------------------------------------------------|
| |
端口位清除寄存器,这个寄存器的低16位和上面寄存器的高16位功能是一样的,该寄存器是为了方便操作设置的,如果只想单一地进行位设置或位清除,那么位设置时用上面的寄存器,位清除时用下面这个寄存器,这样在设置和清除时,使用的都是低16位的数据会方便一点
如果想对多个端口同时进行位设置和位清除,那就使用第一个寄存器就行,这样可以保证位设置和位清除的同步性;如果对信号的同步性要求不高的话,可以先位设置再位清除也ok
|----------------------------------------------------------------------------|
| |
端口配置锁定寄存器,这个可以对端口进行配置进行锁定,防止意外更改