STM32学习笔记(3):通用输入输出端口(GPIO Ports)

注意:本文中所有陈述的内容全部适用于STM32F4系列MCU,其他系列的MCU可能因些许差异不太完全适用。
GPIO和IO的区别:前者可通过自由编程实现复用功能,而后者的功能基本就是固定的或唯一的。
在介绍STM32F4系列MCU的GPIO之前,先来区分一下“接口、端口、引脚”三者的概念。

接口(interface):主机(CPU)与外部设备(指MCU片上外设)之间缓冲电路。它用于完成主机与外部设备设间速度匹配、信号转换,并完成某些控制功能。按数据的传输方式可分为并行接口和串行接口,并行接口指一般I/O接口或通用I/O接口,而串行接口有I2C/SPI/UART等等。

端口(port):I/O接口电路中已经编址并能进行读写操作的寄存器。端口分为数据端口、状态端口及控制端口,普遍存在于各个接口电路中。每个接口电路中都包含一组寄存器,CPU与外部设备进行信息交换时,各类信息在接口中存入不同的寄存器,这些寄存器就是I/O端口,简称I/O口,也称为I/O端口寄存器。

引脚(pin):集成电路与外围电路连接的管脚。

接口(端口)概念是对并行接口和串行接口(I2C/SPI/UART等片上外设)而言的,MCU中大多数的功能模块都有接口电路。狭义上,端口概念往往特指I/O并行接口电路中的寄存器。此外,通常我们所说的“I/O口”指的就是“I/O端口”。

一、GPIO的模式选择

通过GPIO模式寄存器GPIOx_MODER(x是端口名称,x=A…I/J/K)来设置GPIO端口位的方向:
1、输入模式(复位状态
2、GPIO输出模式
3、复用功能模式
4、模拟功能模式
GPIOx_MODER的设置方法,详见技术参考手册TRM。

二、GPIO端口寄存器

每个I/O端口均有下列寄存器,每个端口位均可自由编程,但I/O端口寄存器必须按32位字、半字或字节被访问。其中,GPIOx_BSRR寄存器旨在实现对GPIOx_ODR寄存器进行原子读取/修改访问,具有对GPIOx_ODR按位写权限。

1、4个32位配置寄存器:GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR,这些寄存器位可通过软件写入。其中,输出类型寄存器GPIOx_OTYPER是用1个寄存器位设置1个I/O位,其他配置寄存器均是用2个寄存器位设置1个I/O位。

GPIOx_MODER:选择I/O端口方向为 输入/通用输出/AF/模拟,复位状态为输入。

GPIOx_OTYPER:选择输出类型为 推挽/开漏,复位状态为推挽输出。

GPIOx_OSPEEDR:选择I/O输出驱动电路的响应速度为 低速/中速/快速/高速,用于噪声控制。(由下面Table 22. Port bit configuration table 可知,这个速度寄存器只对输出模式AF起作用)。
注意:GPIO的引脚速度是指I/O口驱动电路的响应速度而不是输出信号的速度,输出信号的速度与程序有关。此外,如果较高频率的信号经过较低频率的驱动电路输出,那么输出的信号就会产生失真,所以驱动电路的频率和信号的频率之间满足采样定理的要求。驱动电路的频率应该适当不能过大(建议10~20倍于信号的频率),以便降低噪声、功耗和电磁辐射。

GPIOx_PUPDR:选择I/O端口为 无上拉或下拉/上拉/下拉/保留(与IO端口方向无关)。

2、2个32位数据寄存器:GPIOx_IDR、GPIOx_ODR

GPIOx_IDR:这些寄存器位为只读 形式,并且只能模式下访问。

GPIOx_ODR:这些寄存器位可通过软件读取和写入。

3、1个32位置位复位寄存器:GPIOx_BSRR

GPIOx_BSRR低半字用来置位GPIOx_ODR,即写入“1”,而高半字用来复位GPIOx_ODR,即写入“0”。GPIOx_BSRR旨在对GPIOx_ODR寄存器进行原子读写操作,它只能在字、半字、字节模式下被访问对GPIOx_ODR进行原子操作。

4、1个32位锁定寄存器:GPIOx_LCKR

锁定寄存器GPIOx_LCKR的每个锁定位用于锁定端口位的配置。冻结的寄存器包括:GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR、GPIOx_AFRH、GPIOx_AFRL,它只能以字的方式被访问。锁定寄存器锁定配置后,就会避免因意外改写端口寄存器配置造成大电流损坏芯片的故障或其他故障。

5、2个32位复用功能选择寄存器:GPIOx_AFRH、GPIOx_AFRL

GPIOx_AFRL:用四位寄存器位选择一个对应的复用功能。该寄存器用于选择AF0~AF7。

GPIOx_AFRH:用四位寄存器位选择一个对应的复用功能。该寄存器用于选择AF8~AF15。

复用功能选择寄存器只能通过字被访问。

三、GPIO的工作模式

通过对4种端口配置寄存器进行编程,可将GPIO口的各个端口位配置成以下8种工作模式:

输入+悬空
输入+上拉
输入+下拉
模拟(用作ADC输入、DAC输出或者捕获输入情况下)
输出+开漏+上拉/下拉(输出模式时GPIO的输出速度是可配置的)
输出+推挽+上拉/下拉(输出模式时GPIO的输出速度是可配置的)
复用功能+推挽+上拉/下拉(复用功能时速度是可配置的)
复用功能+开漏+上拉/下拉(复用功能时速度是可配置的)

四、GPIO 8种工作模式端口位的结构

STM32学习笔记(3):通用输入输出端口(GPIO Ports)_第1张图片 STM32学习笔记(3):通用输入输出端口(GPIO Ports)_第2张图片

图1是GPIO端口位的电路结构:
● I/O输入通道有个TTL施密特触发器,它用于将变化缓慢的输入信号整形成边沿陡峭的矩形脉冲。同时,施密特触发器利用其回差电压提高了电路的抗干扰能力;
● 所有的I/O口均兼容TTL电平和CMOS电平;
● 大多数I/O是5V电压容限(FT 结构的I/O是5V容限,其他结构的I/O不是。详细情况请参见相应的STM32F4数据手册);
● 当GPIO被配置为模拟功能时,I/O不再是5V电压容限,这时以VDDA为电压容限;
● 除了端口A和B(主要是PA13/PA14/PA15/PB3/PB4这5个端口位复位后专门用于片上调试模块,不受4个GPIO控制寄存器控制),其他端口的所有端口位复位期间或者复位后都是悬空输入状态;
● 输出通道中,输出数据寄存器和复用功能输出接到多路复用器,再经过输出控制连接到推挽电路的门极。值得注意的是输出控制会将输出数据寄存器和复用功能输出的电平进行反转(即’1’变’0’,’0’变’1’)。仔细观察会发现P-MOS管的门极有个小圈“。”,它表示P-MOS的门极为低电平’0’时,P-MOS导通。反之,N-MOS是门极为高电平’1’时导通;
● 推挽输出的驱动能力强,并且推挽输出时,若P-MOS导通,引脚上的电压不会因为外部器件或设备(即引脚带负载)而有所降低;
● I/O端口位的最大状态切换频率为90MHZ。


STM32学习笔记(3):通用输入输出端口(GPIO Ports)_第3张图片

由图2可以看出,当I/O端口被配置为输入时:
● 输出缓冲器被禁止;
● 施密特触发输入被激活;
● 根据寄存器GPIOx_PUPDR中的值选择引脚为弱上拉或弱下拉或悬空输入;
● I/O引脚上的数据在每个AHB1时钟周期被采样到输入数据寄存器;
● 对输入数据寄存器的读访问可获得I/O状态。


STM32学习笔记(3):通用输入输出端口(GPIO Ports)_第4张图片

由图3可以看出,当I/O端口被配置为GPIO输出时:
● 输出缓冲器被激活
─ 开漏模式:输出寄存器上的 ‘0’ 激活N-MOS,而输出寄存器上的 ‘1’ 将端口置于高阻状态(PMOS从不被激活);
─ 推挽模式:输出寄存器上的 ‘0’ 激活N-MOS,而输出寄存器上的 ‘1’ 将激活P-MOS;
● 施密特触发器输入被激活;
● 选择引脚为弱上拉或弱下拉输出或悬空;
● I/O脚上的数据在每个AHB1时钟周期被采样到输入数据寄存器;
● 对输入数据寄存器的读访问可得到I/O状态;
● 对输出数据寄存器的读访问得到最后一次写的值。


STM32学习笔记(3):通用输入输出端口(GPIO Ports)_第5张图片

由图4可以看出,当I/O端口被配置为复用功能AF(Alternate Function)时:
● 输出缓冲器可以被配置成开漏或推挽;
● 输出缓冲器被片上外设信号驱动;
● 施密特触发器输入被激活;
● 根据寄存器GPIOx_PUPDR中的值选择引脚为弱上拉或弱下拉或悬空输出;
● I/O脚上的数据在每个AHB1时钟周期被采样到输入数据寄存器;
● 对输出数据寄存器的读访问得到最后一次写的值。


STM32学习笔记(3):通用输入输出端口(GPIO Ports)_第6张图片

由图5可以看出,档I/O端口被配置为模拟功能时:
● 输出缓冲器被禁止;
● 施密特触发器输入被暂停,0功耗,并且输出一直维持在0值状态;
● 管脚的弱上拉和下拉被禁止;
● 访问输入数据寄存器得到的数值为0;


五、GPIO引脚作为一般IO输入时,引脚的状态和端口输入寄存器GPIOx_IDR的状态是否一致?

在学习51核单片机时,由于51单片机I/O接口电路结构的原因,I/O输入时,I/O的引脚状态会出现与锁存器不一样的情况。所以,往往在I/O上拉输入前,提前向锁存器写入“1”,指令上也分为读引脚和读锁存器指令。

那么,基于Cortex-M内核的MCU的I/O引脚输入时是否也有与51单片机同样的问题呢??

答案是否定的!因为Cortex-M内核的MCU的GPIO引脚在被配置为I/O输入时,其输出电路是断开的。这样,输出电路就不会影响到引脚的状态。所以,引脚上的状态和输入寄存器GPIOx_IDR中的数据始终一致。

你可能感兴趣的:(STM32F429)