一、前言
在之前的STM32的GPIO理论基础知识中,分别对基本结构和工作模式进行了详细的介绍。 GPIO基本结构中主要对GPIO内部的各个功能电路逐一的进行的分析; GPIO工作模式中主要介绍GPIO应用在不同的使用场景下,GPIO端口的静态特征配置和动态的工作模式,同时对信号的工作流进行了分析。
这一篇主要对GPIO模块使用到的寄存器进行详细的分析介绍,适当了解GPIO寄存器的相关知识,可以对GPIO最底层的一些配置和工作原理有更好的认识,有助于加深对GPIO基本结构及工作模式的理解,同时对后续介绍到的GPIO在应用设计中有较好的帮助。
二、寄存器概述
图1为STM32的GPIO模块中寄存器的概述,总共有5种类型的寄存器。 这里需要了解的是GPIO模块的port和pin的概念。 其中寄存器名称中GPIOx的x表示不同的GPIO端口port,比如STM32芯片支持的port可以从A到I,GPIOA,GPIOB就表示了不同的端口; pin就是不同的port下支持的引脚,比如GPIOA下的引脚数从pin0到pin15。 因此port就是pin的集合,不同的port都有它自己的如下图列出来的寄存器。
图1 GPIO寄存器概述
三、寄存器详述
本节对寄存器位、寄存器偏移地址、复位值、寄存器功能定义进行介绍。 可通过字节(8 位)、半字(16 位)或字(32 位)对 GPIO 寄存器进行访问。
(1)端口模式寄存器GPIOx_MODER
本寄存器的功能为设置GPIO端口的方向和模式,总共0到32位,每两位就是该port下的pin值,例如将GPIOA_MODER的MODER0[1:0]配置为00,就是将GPIOA的pin0管脚功能配置为输入类型的管脚,将GPIOA_MODER的MODER1[1:0]配置为00,就是将GPIOA的pin1管脚功能配置为输入类型的管脚, 以此类推。
图2 GPIOx_MODER寄存器定义
(2)端口输出类型寄存器GPIOx_OTYPER
本寄存器设置GPIO端口的输出类型,前提是该端口中的pin已经配置成输出功能。 该寄存器只有0到15位有效,每一位就是对应的pin值,例如将GPIOA_OTYPER的OT0设置为1,就是将GPIOA的pin0管脚设置为输出开漏的类型。
图3 GPIOx_OTYPER寄存器定义
(3)端口输出速度寄存器GPIOx_OSPEEDR
本寄存器设置GPIO的输出速度频率,前提是该端口中的pin已经应用作为输出功能管脚。
这个速度是指输出驱动电路的响应速度:(芯片内部在I/O口的输出部分安排了多个响应速度不同的输出驱动电路,用户可以根据自己的需要选择合适的驱动电路,通过选择速度来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。 可理解为输出驱动电路的带宽:即一个驱动电路可以不失真地通过信号的最大频率。
速度高的IO耗电大、噪声也大,速度低的IO耗电小、噪声也小。 使用合适的速度可以降低功耗和噪声。 高频的驱动电路,噪声也高,当不需要高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能,也可以降低功耗。 当然如果要输出较高频率的信号,但却选用了较低频率的速度,很可能会得到失真的输出信号。 关键是GPIO的引脚速度跟应用匹配。
比如:
①USART串口,若最大波特率只需115.2k,那用2M的速度就够了,既省电也噪声小。
②I2C接口,若使用400k波特率,若想把余量留大些,可以选用10M的GPIO引脚速度。
③SPI接口,若使用18M或9M波特率,需要选用50M的GPIO的引脚速度。
当为该端口下寄存器值的pin配置为11时,输出速度和电容C有关,这是指对于CMOS工艺的集成电路而言,输入阻抗是非常高的,主要功耗来自于绝缘栅等效的电容充放电效应。 既然是电容的充放电,考虑信号源的内阻(基于标准CMOS电路的输出),根据RC充电常数和逻辑门限电平就能得出一个最小周期,其对应一个最高IO频率。
图4 GPIOx_OSPEEDR寄存器定义
(4)端口上拉/下拉寄存器GPIOx_PUPDR
该寄存器是配置端口对应的pin上是否需要配置芯片内部的上拉或者下拉电阻。
图5 GPIOx_PUPDR寄存器定义
STM32芯片GPIO的上拉电阻和下拉电阻最小值,典型值和最大值如下:
(5)端口输入数据寄存器 GPIOx_IDR
本寄存器读取GPIO端口引脚的信号电平值。 该寄存器只有0到15位有效,每一位就是对应的pin值,例如GPIOA_OTYPER的IDR00值为1,就是此时读到GPIOA的pin0管脚值为1高电平信号。
图6 GPIOx_IDR寄存器定义
(6)GPIO 端口输出数据寄存器 GPIOx_ODR
本寄存器可以设置GPIO端口引脚的信号值。 前提是该引脚为普通的IO输出引脚。 该寄存器只有0到15位有效,每一位就是对应的pin值,例如设置GPIOA_OTYPER的ODR0值为1,就是此时输出GPIOA的pin0管脚值为1高电平信号。
图7 GPIOx_ODR寄存器定义
(7)GPIO 端口置位/复位寄存器GPIOx_BSRR
本寄存器可以通过写入GPIOx_BSRR寄存器值,可以对GPIOx_ODR的对应位进行置位和复位。 既然GPIOx_ODR 能控制管脚高低电平,为什么还需要GPIOx_BSRR寄存器?
原因是GPIOx_BSRR去改变管脚状态的时候是原子操作置位/复位,没有被中断打断的风险。 也就不需要关闭中断,关闭中断明显会延迟或丢失一事件的捕获,所以控制GPIO的状态最好可以用GPIOx_BSRR。
该寄存器的0到15位为置位功能,16到31位为复位功能。 例如设置GPIOA_BSRR的BS0值为1,相当于输出GPIOA的pin0管脚值为1高电平信号; 设置GPIOA_BSRR的BR0值为1,相当于输出GPIOA的pin0管脚值为0低电平信号。
图8 GPIOx_BSRR寄存器定义
(8)GPIO 端口配置锁定寄存器GPIOx_LCKR
本寄存器用于锁定当前管脚的配置,可以保持管脚当前的状态,保护管脚不受干扰,要使用该寄存器,需要先激活“锁定”功能。 当执行正确的写序列设置了位16(LCKK)时,锁定功能被激活,LCKK位的写序列为:写1 -> 写0 -> 写1 -> 读0 -> 读1。 最后一个读可省略,但可以用来确认锁键已被激活。 被锁定的管脚pin只有等到下次MCU复位才能被解锁。
LCK0到LCK15为对应的pin0到pin15的锁定配置,当需要锁定对应的管脚pin时,在执行LCKK写序列操作时,将对应的LCK位写1。
图9 GPIOx_LCKR寄存器定义
(9)GPIO 复用功能低位寄存器GPIOx_AFRL
本寄存器可以设置GPIO端口引脚的复用功能,比如将该引脚设置成USART或者SPI类型的功能管脚,本寄存器AFRL0 ~ AFRL7分别对应引脚pin0~pin7,每个引脚又有4位可选,因此一个引脚可以在16中复用功能中选择,例如将GPIOA_AFRL的AFRL0[3:0]= 0001,就是将GPIOA的pin0管脚应用成第2种复用功能AF1。
图10 GPIOx_AFRL寄存器定义
(10)GPIO 复用功能高位寄存器GPIOx_AFRH
本寄存器可以设置GPIO端口引脚的复用功能,本寄存器AFRL0 ~ AFRL7分别对应引脚pin0~pin7,功能上和复用功能低位寄存器GPIOx_AFRL一样。
图11 GPIOx_AFRH寄存器定义
四、总结
本篇对STM32的GPIO对应的寄存器分别进行了介绍,了解了各个寄存器的功能和对应寄存器位的定义可以更方便的去理解在实际使用GPIO时的配置功能,后续篇章将对GPIO在实际开发中的设计配置及应用进行详细的分析。