IOMUXC_SW_MUX_CTL_PAD_XX_XX 和 IOMUXC_SW_PAD_CTL_PAD_XX_XX 这两种寄存器都是配置 IO 的,注意是 IO!不是 GPIO,GPIO 是一个 IO 众多复用功能中的一种。比如 GPIO1_IO00 这个 IO 可以复用为:I2C2_SCL、GPT1_CAPTURE1、ANATOP_OTG1_ID、ENET1_REF_CLK 、 MQS_RIGHT 、 GPIO1_IO00 、 ENET1_1588_EVENT0_IN 、SRC_SYSTEM_RESET 和 WDOG3_WDOG_B 这 9 个功能,GPIO1_IO00 是其中的一种,我们想要把 GPIO1_IO00 用作哪个外设就复用为哪个外设功能即可。如果我们要用 GPIO1_IO00 来点个灯、作为按键输入啥的就是使用其GPIO(通用输入输出)的功能。将其复用为 GPIO 以后还需要对其 GPIO 的功能进行配置,关于 I.MX6U 的 GPIO 请参考《IMX6UL 参考手册》的第 26章“Chapter 26 General Purpose Input/Ouput(GPIO)”,GPIO 结构如图所示:
GPIO 结构图
在图 的 左 下 角 的 IOMUXC 框 图 里 面 就 有 SW_MUX_CTL_PAD_* 和SW_PAD_CTL_PAD_*两种寄存器。这两种寄存器前面说了用来设置 IO 的复用功能和 IO 属性配置。左上角部分的 GPIO 框图就是,当 IO 用作 GPIO 的时候需要设置的寄存器,一共有八个:
DR、GDIR、PSR、ICR1、ICR2、EDGE_SEL、IMR 和 ISR。前面我们说了 I.MX6U 一共有GPIO1~GPIO5 共五组 GPIO,每组 GPIO 都有这 8 个寄存器。我们来看一下这 8 个寄存器都是什么含义。
首先来看一下 DR 寄存器,此寄存器是数据寄存器,结构图如图所示:
DR 寄存器结构图
此寄存器是 32 位的,一个 GPIO 组最大只有 32 个 IO,因此 DR 寄存器中的每个位都对应一个 GPIO。当 GPIO 被配置为输出功能以后,向指定的位写入数据那么相应的 IO 就会输出相应的高低电平,比如要设置 GPIO1_IO00 输出高电平,那么就应该设置GPIO1.DR=1。当 GPIO被配置为输入模式以后,此寄存器就保存着对应 IO 的电平值,每个位对对应一个 GPIO,例如,当 GPIO1_IO00 这个引脚接地的话,那么 GPIO1.DR 的bit0 就是 0。
看完 DR 寄存器,接着看 GDIR 寄存器,这是方向寄存器,用来设置某个 GPIO 的工作方向的,即输入/输出,GDIR 寄存器结构如图所示:
GDIR 寄存器
GDIR 寄存器也是 32 位的,此寄存器用来设置某个 IO 的工作方向,是输入还是输出。同样的,每个IO 对应一个位,如果要设置GPIO 为输入的话就设置相应的位为 0,如果要设置为输出的话就设置为 1。比如要设置GPIO1_IO00 为输入,那么GPIO1.GDIR=0;接下来看 PSR 寄存器,这是 GPIO 状态寄存器,如图所示:
PSR 状态寄存器
同样的 PSR 寄存器也是一个 GPIO 对应一个位,读取相应的位即可获取对应的 GPIO 的状态,也就是GPIO 的高低电平值。功能和输入状态下的 DR 寄存器一样。接下来看ICR1 和ICR2 这两个寄存器,都是中断控制寄存器,ICR1 用于配置低16 个GPIO,ICR2 用于配置高 16 个GPIO,ICR1 寄存器如图所示:
ICR1 寄存器
ICR1 用于 IO0~15 的配置, ICR2 用于 IO16~31 的配置。ICR1 寄存器中一个GPIO 用两个位,这两个位用来配置中断的触发方式,和 STM32 的中断很类似,可配置的选线如表所示:
中断触发配置
以GPIO1_IO15 为例,如果要设置GPIO1_IO15 为上升沿触发中断,那么GPIO1.ICR1=2<<30,如果要设置GPIO1 的 IO16~31 的话就需要设置 ICR2 寄存器了。接下来看 IMR 寄存器,这是中断屏蔽寄存器,如图所示:
IMR 寄存器
IMR 寄存器也是一个 GPIO 对应一个位,IMR 寄存器用来控制 GPIO 的中断禁止和使能,如果使能某个 GPIO 的中断,那么设置相应的位为 1 即可,反之,如果要禁止中断,那么就设置相应的位为 0 即可。例如,要使能 GPIO1_IO00 的中断,那么就可以设置 GPIO1.MIR=1 即可。
接下来看寄存器 ISR,ISR 是中断状态寄存器,寄存器如图所示:
ISR 寄存器
ISR 寄存器也是 32 位寄存器,一个GPIO 对应一个位,只要某个 GPIO 的中断发生,那么ISR 中相应的位就会被置 1。所以,我们可以通过读取 ISR 寄存器来判断 GPIO 中断是否发生,相当于 ISR中的这些位就是中断标志位。当我们处理完中断以后,必须清除中断标志位,清除方法就是向ISR 中相应的位写 1,也就是写 1 清零。
最后来看一下EDGE_SEL 寄存器,这是边沿选择寄存器,寄存器如图所示:
EDGE_SEL 寄存器
EDGE_SEL 寄存器用来设置边沿中断,这个寄存器会覆盖 ICR1 和 ICR2 的设置,同样是一个 GPIO 对应一个位。如果相应的位被置 1,那么就相当与设置了对应的 GPIO 是上升沿和下降沿(双边沿)触发。例如,我们设置 GPIO1.EDGE_SEL=1,那么就表示 GPIO1_IO01 是双边沿触发中断,无论GFPIO1_CR1 的设置为多少,都是双边沿触发。
关于GPIO 的寄存器就讲解到这里,因为 GPIO 是最常用的功能,我们详细的讲解了 GPIO的 8 个寄存器。