i.MX6ULL也有多种点灯方式:(究其本质,最终都是要操作i.MX6ULL的寄存器)

  • 裸机系统:汇编操作寄存器点灯、C语言操作寄存器点灯
  • 跑Linux系统:字符驱动LED点灯、设备树驱动LED点灯

IO与GPIO是两个概念,GPIO是属于IO的一部分。

IO: Input Output,用于CPU与外界进行信息交互。例如CPU 读内存数据需要 I/O 系统,CPU 输出数据到屏幕显示出来也需要 I/O 系统,信息在 I/O 系统上传输有串行或并行。
GPIO: General-Purpose IO ports,即通用I/O口,在微控制器芯片上一般都会提供一个“通用可编程I/O接口”。接口至少有两个寄存器——数据寄存器与控制寄存器。数据寄存器的各位直接引到芯片外部,控制寄存器则是对数据寄存器中每一位进行独立的设置。

imx6ul的GPIO硬件结构

① PAD:它代表了i.MX6ULL芯片的一个GPIO引脚。

② IOMUX复用选择器:与STM32的引脚复用功能类似,i.MX6ULL芯片的每个IO通过IOMUXC中的MUX寄存器和PAD寄存器设置,可以支持多种功能(如GPIO、IIC、USART…)。

IOMUX由其左侧的IOMUXC提供寄存器给用户进行配置,它又分成MUX_Mode(IO 模式控制)以及Pad Settings(Pad 配置)两个部分:

  1. MUX_Mode配置:用来配置引脚的复用功能

    2.Pad Settings 配置:配置引脚的属性,例如驱动能力,是否使用上下拉电阻,是否使用保持器,是否使用开漏模式以及使用施密特模式还是CMOS模式等

③ Block外设功能控制块:例如具有PWM输出功能的引脚,它需要PWM外设的支持。

④ GPIO外设:GPIO模块是每个IO都具有的外设, 它是IO控制的基本功能, 如输出高低电平、 检测电平输入等。当需要使用引脚的GPIO功能时,就要配置GPIO外设中的各个寄存器(DR、GDIR、PSR…)。

⑤ 与其它引脚的连接:这里是另一个引脚PAD2,它与PAD1有一根信号线连接,表示部分引脚的输出可以作为另一个引脚的输入。

GPIO配置

1
2
3
4
5
6
7
8
9
10
typedef struct {
__IO uint32_t DR; /**< GPIO data register, offset: 0x0 */
__IO uint32_t GDIR; /**< GPIO direction register, offset: 0x4 */
__I uint32_t PSR; /**< GPIO pad status register, offset: 0x8 */
__IO uint32_t ICR1; /**< GPIO interrupt configuration register1, offset: 0xC */
__IO uint32_t ICR2; /**< GPIO interrupt configuration register2, offset: 0x10 */
__IO uint32_t IMR; /**< GPIO interrupt mask register, offset: 0x14 */
__IO uint32_t ISR; /**< GPIO interrupt status register, offset: 0x18 */
__IO uint32_t EDGE_SEL; /**< GPIO edge select register, offset: 0x1C */
} GPIO_Type;

DR(data register),即数据寄存器,它是32位的,一个GPIO组最大只有32个IO,因此DR寄存器中的每个位都对应一个 GPIO。当GPIO被配置为输出模式后,向指定的位写入数据那么相应的IO就会输出相应的高低电平,当 GPIO被配置为输入模式后,此寄存器就保存着对应IO的电平值,每个位对对应一个GPIO。

GDIR(GPIO direction register),即方向寄存器,也是32位的,用来设置某个GPIO的工作方向的,即输入/输出。同样的,每个IO对应一个位,如果要设置GPIO为输入,就设置相应的位为0,如果要设置为输出,就设置为1

PSR(Pad Status Register),即状态寄存器,也是32位的。注意它是一个只读寄存器,每个IO对应一个位,读取相应的位即可获取对应的GPIO的状(高低电平值),功能和输入状态下的DR寄存器一样。

ICR1(interrupt configuration register1)和ICR2,都是中断控制寄存器, ICR1用于配置低16个GPIO,ICR2 用于配置高16 个GPIO。

IMR(interrupt mask register),即中断屏蔽寄存器,也是32位,每个IO对应一个位。IMR寄存器用来控制GPIO的中断禁止和使能,如果使能某个GPIO的中断,那么设置相应的位为1即可,反之,如果要禁止中断,那么就设置相应的位为0即可。

ISR(interrupt status register),即中断状态寄存器,也是32位,每个IO对应一个位。只要某个GPIO的中断发生,则ISR中相应的位就会被置1。所以通过读取ISR寄存器来判断是否发生了中断,类似于学习STM32用到的中断标志位。

EDGE_SEL(edge select register),即边沿选择寄存器,也是32位,每个IO对应一个位。

它用来设置边沿中断, 并会覆盖ICR1和ICR2的设置。

时钟配置

CCM(Clock Controller Module)时钟控制模块寄存器用来使能外设时钟。 CMM一共有CCM_CCGR0~CCM_CCGR6这 7 个寄存器,控制着I.MX6U的所有外设时钟开关。

以CCM_CCGR0为例,它是个32位寄存器,每2位控制一个外设的时钟,比如 bit31:30 控制着GPIO2 的外设时钟,两个位就有 4 种操作方式:

位设置 时钟控制
00 所有模式下都关闭外设时钟
01 只有在运行模式下打开外设时钟,等待模式和停止模式下均关闭外设时钟
10 未使用(保留)
11 除了停止模式以外,其他所有模式下时钟都打开

配置总结
使用i.MX6ULL的GPIO时,需要如下几步配置:

使能 GPIO 对应的时钟
配置MUX寄存器,设置IO的复用功能,使其复用为GPIO功能
配置PAD寄存器,设置 IO 的上下拉、速度等
配置GPIO的各种寄存器(DR、GDIR、…),设置输入/输出、是否使用中断、默认输出电平等