i.MX RT开发笔记-06 | i.MX RT1062 使用 IOMUXC 和 GPIO 点亮LED

Posted Mculover666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了i.MX RT开发笔记-06 | i.MX RT1062 使用 IOMUXC 和 GPIO 点亮LED相关的知识,希望对你有一定的参考价值。

系列文章目录

一、IOMUXC外设

1. I/O引脚(pin或pad)

I/O引脚是指芯片肉眼可见的输入输出引脚,也称为pin。

引脚数量的多少通常由封装决定,比如本文中所使用的i.MXRT1062CVL5B芯片,使用 BGA 封装,总共有196个引脚:

在数据手册中(IMXRT1060CEC)可以看到这 196 个引脚的名称以及默认功能映射表(Table 83,部分截取):

2. GPIO外设和I/O引脚的关系(IOMUXC外设)

GPIO(General Purpose Input/Output)是芯片内的外设,每个GPIO外设连接到了外部的I/O引脚上,这时,和GPIO外设相连的I/O引脚起着通用输入输出的功能,所以被称为 GPIO 引脚。

但是,I/O引脚不仅可以和GPIO外设相连,还可以和芯片内部其它外设相连,比如和UART、IIC、SPI等外设相连作为通信外设的接口引脚,和定时器相连作为PWM输出引脚,等等。

基于这种设计,i.MX RT1062 提供了 IOMUX单元(I/O复用选择器),可以选通I/O引脚与某个具体的外设相连,发挥不同的作用。

一个IOMUX单元最大支持选择 8 个功能,称为ALT,不同的模式分别称为ALT0-ALT7,所以在阅读数据手册时,看到ALT这个英文缩写不要惊讶。

那么,如何控制IOMUX选通某个具体的功能呢?

芯片内部提供了 IOMUXC外设 来控制IOMUX单元,由图中可以看到,IOMUXC有两个作用:

  • SW_MUX_CTL_PAD*寄存器:用于设置某个引脚的IOMUX,选择该引脚的功能;
  • SW_PAD_CTL_PAD*寄存器:用于设置某个引脚的属性,比如驱动能力、是否使用上下拉电阻等;

两个寄存器名称中的 * 表示引脚名称,比如 GPIO_AD_B0_00 引脚的这两个寄存器为:

① SW_MUX_CTL_PAD_GPIO_AD_B0_00



② SW_PAD_CTL_PAD_GPIO_AD_B0_00



该寄存器中每个配置项的作用如下表:

配置项作用
HYS是否使用施密特触发器
PUS是否使用上拉/下拉(输入模式有效)
PUE选择上下拉或者保持器
PKE使能上下拉或者保持器
ODE开漏使能(需要外接上拉电阻)
SPEED引脚速度
DSE驱动能力(会串联一个电阻,阻值可选)
SRE压摆率

综上所述,i.MXRT1062这 196 个引脚,除了一些用作特殊功能(电源、时钟等)的引脚之外,每个功能引脚都需要一个 IOMUX单元来配合才行

二、GPIO外设(GPIO)

RT1062芯片有5个GPIO外设,分别为GPIO1-5,每个GPIO外设可以控制32个GPIO引脚

每个GPIO外设的框图如下,主要有8个寄存器:

1. 设置 GPIO 引脚方向

通过配置 GPIO 方向寄存器 GDIR(GPIO Direction register) 来设置GPIO引脚的方向:

GDIR寄存器中的32位对应该GPIO外设的32个引脚,置0为输入,置1为输出:

2. 读取/写入 GPIO 数据寄存器

GPIO引脚的电平数据存放在 GPIO数据寄存器 DR (Data Register)中:

三、外设时钟使能

i.MX RT1062的时钟管理单元为CCM(Clock Controller Module),为了保持低功耗,每个外设的时钟是独立且失能的。

本实验中使用了 IOMUXC 和 GPIO1 两个外设,需要使能这两个外设的时钟。

在参考手册 GPIO 章节的 Clock 小节说明了 GPIO 的时钟源:

在参考手册 IOMUCX 章节的 Clock 小节说明了 IOMUCX 的时钟源:

在参考手册 CCM 章节可以看到(Table 18-3)GPIO1外设的时钟源和时钟增益使能寄存器:

查阅 CCM_CCGR1(CCM Clock Gating Register 1 )寄存器描述

其中 CG13 位用来控制GPIO1外设的时钟:

那么,这两位的值应该设置为多少呢?参考手册中也已给出:

四、点亮LED

1. 查看原理图

USER_LED 引脚连接至 GPIO_AD_B0_00 引脚。

2. 编写寄存器定义

在上一篇文章中,新建了一个空的头文件MIMXRT1062.h用于存放寄存器定义,根据本文之前所讲述的资料,将GPIO控制相关的寄存器全部定义:

#ifndef MIMXRT1062_H_
#define MIMXRT1062_H_

/* CCM */
#define CCM_BASE    (unsigned int)(0x400FC000)
#define CCM_CCGR1   *(unsigned int*)(CCM_BASE + 0x6C)

/* IOMUCX */
#define IOMUXC_BASE (unsigned int)(0x401F8000)
#define IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_00 *(unsigned int*)(IOMUXC_BASE + 0xBC)
#define IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_00 *(unsigned int*)(IOMUXC_BASE + 0x2AC)

/* GPIO1 */
#define GPIO1_BASE  (unsigned int)(0x401B8000)
#define GPIO1_DR    *(unsigned int*)(GPIO1_BASE + 0x00)
#define GPIO1_GDIR  *(unsigned int*)(GPIO1_BASE + 0x04)

#endif /* MIMXRT1062_H_ */

3. 编写主函数

#include "MIMXRT1062.h"

int main(void)
{	
	/* Enable GPIO1 Clock */
	CCM_CCGR1 &= ~(unsigned int)(3<<26);    // bit27 = 0, bit 26 = 0
	CCM_CCGR1 |= (unsigned int)(1<<26);     // bit26 = 1
		
	/* Set GPIO_AD_B0_00 as GPIO1.0 */
	IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_00 = (unsigned int)0x05;
	
	/* Set pad parameters of GPIO1.0 */
	IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_00 = (unsigned int)0x000B0;
    
	/* set output mode */
	GPIO1_GDIR |= (unsigned int)(1<<0);

	/* output low level */
	GPIO1_DR &= ~(unsigned int)(1<<0);
	
	while(1);
}

void SystemInit(void)
{	
}

4. 实验结果

编译、进入调试模式、全速运行,即可看到 LED 被点亮:

以上是关于i.MX RT开发笔记-06 | i.MX RT1062 使用 IOMUXC 和 GPIO 点亮LED的主要内容,如果未能解决你的问题,请参考以下文章

i.MX RT开发笔记-03 | i.MX RT1062地址空间映射

i.MX RT开发笔记-08 | i.MX RT1062嵌套中断向量控制器NVIC(按键中断检测)

痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.B)- FlexSPI NOR连接方式大全(RT1160/1170)...

i.MX RT开发笔记-01 | 初识 i.MX RT1062 跨界MCU

i.MX RT开发笔记-02 | i.MX RT1062开发环境搭建(MDK芯片包NXP SDK详解)

i.MX RT开发笔记-05 | 新建 MDK 不同版本工程(SRAM调试版本Nor Flash下载版本)