第八章 汇编 LED 灯实验学习

您所在的位置:网站首页 红米airdots2音量变小 第八章 汇编 LED 灯实验学习

第八章 汇编 LED 灯实验学习

2023-03-13 19:37| 来源: 网络整理| 查看: 265

本章使用汇编语言来编写,通过本章了解如何使用汇编语言来初始化 I.MX6ULL 外设寄存器、了解 I.MX6ULL 最基本的 IO 输出功能。

8.1 I.MX6ULL GPIO 详解

8.1.1 STM32 GPIO 回顾

初始化代码中重点要做的事情有一下几个:

①、使能指定 GPIO 的时钟;

②、初始化 GPIO,比如输出功能、上拉、速度等等;

③、 STM32 有的 IO 可以作为其它外设引脚,也就是 IO 复用,如果要将 IO 作为其它外设引脚使用的话就需要设置 IO 的复用功能;

④、最后设置 GPIO 输出高电平或者低电平。

其中I.MX6ULL的设置需要看了数据手册和参考手册,IMX6ULL 参考手册.pdf和IMX6ULL 数据手册(商用级)pdf。

8.1.2 I.MX6U IO 命名

I.MX6ULL 参考手册的第 32 章“Chapter 32: IOMUX Controller(IOMUXC)”,第 32 章的书签如图 8.1.2.1 所示:

图 8.1.2.1 I.MX6U GPIO 命名

I.MX6ULL 的 IO 分为两类: SNVS 域的和通用的,这两类 IO 本质上都是一样的,我们就有下面的常用 IO 为例,讲学习下 I.MX6ULL 的 IO 命名方式。

图 8.1.2.1 中的形如“IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00”的就是 GPIO 命名,命名形式就是“IOMUXC_SW_MUC_CTL_PAD_XX_XX”,后面的“XX_XX”就是 GPIO 命名,

比如: GPIO1_IO01、 UART1_TX_DATA、 JTAG_MOD 等等

注意:I.MX6ULL 的 GPIO 并不像 STM32一样以 PA0~15 这样命名,他是根据某个 IO 所拥有的功能来命名的。

8.3.1 I.MX6U IO复用

以“IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00”这个 IO 为例,打开参考手册的 1568 页,如图 8.1.3.1 所示:

图 8.1.3.1 GPIO1_IO00 复用

从图 8.1.3.1 可以看到有个名为: IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00 的寄存器,寄存器地址为 0X020E005C,这个寄存器是 32 位的,但是只用到了最低 5 位,其中

bit0~bit3(MUX_MODE)就是设置 GPIO1_IO00 的复用功能的。 GPIO1_IO00 一共可以复用为 9种功能 IO, 分别对应 ALT0~ALT8,其中 ALT5 就是作为 GPIO1_IO00。 GPIO1_IO00 还可以作

为 I2C2_SCL、 GPT1_CAPTURE1、 ANATOP_OTG1_ID 等。这个就是 I.MX6U 的 IO 复用,我们学习 STM32 的时候 STM32 的 GPIO 也是可以复用的。

再来看一个“IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA”这个 IO,这个 IO 对应的复用如图 8.1.3.2 所示:

图 8.1.3.2 UART1_TX_DATA IO 复用

同样的,从图 8.1.3.2 可以看出, UART1_TX_DATA 可以复用为 8 种不同功能的 IO,分为ALT0~ALT5 和 ALT8、 ATL9,其中 ALT5 表示 UART1_TX_DATA 可以复用为 GPIO1_IO16。

I.MX6ULL 的 GPIO 一共有 5 组: GPIO1、 GPIO2、 GPIO3、 GPIO4 和 GPIO5,其中 GPIO1 有 32 个 IO, GPIO2 有 22 个 IO, GPIO3 有 29 个 IO、 GPIO4 有 29 个 IO, GPIO5

最少,只有 12 个 IO,这样一共有 124 个 GPIO。如果只想看每个 IO 能复用什么外设的话可以直接查阅《IMX6ULL 参考手册》的第 4 章“Chapter 4 External Signals and Pin Multiplexing”。如

果我们要编写代码,设置某个 IO 的复用功能的话就需要查阅第 32 章“Chapter 32: IOMUXController(IOMUXC)” ,第 32 章详细的列出了所有 IO 对应的复用配置寄存器。

注意:I.MX6U 的 IO 是有复用功能的,和 STM32一样,如果某个 IO 要作为某个外设引脚使用的话,是需要配置复用寄存器的。

8.1.4 I.MX6U IO 配置

《 I.MX6UL 参考手册》第 30 章“ Chapter 30: IOMUX Controller(IOMUXC)”的书签中,每一个 IO 会出现两次:

IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00

IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00

上面两个都是跟 GPIO_IO00 有关的寄存器,名字上的区别就是红色部分,一个是“MUX”,一个是“PAD”。

IOMUX_SW_MUX_CTL_PAD_GPIO1_IO00 --- 用来配置GPIO1_IO00 复用功能的,

IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 --- 用来配置GPIO1_IO00 包括速度设置、驱动能力设置、压摆率设置等等

图 8.1.4.1 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 寄存器

从图 8.1.4.1 中可以看出, IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 也是个寄存器,寄存器地址为 0X020E02E8。这也是个 32 位寄存器,但是只用到了其中的低 17 位,先来看一下图 8.1.4.2 所示的 GPIO 功能图:

图 8.1.4.2 GPIO 功能图

对照着图 8.1.4.2 来详细看一下寄存器 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 的各个位的含义:

HYS(bit16):对应图 8.1.4.2 中 HYS,用来使能迟滞比较器,当 IO 作为输入功能的时候有效,用于设置输入接收器的施密特触发器是否使能。如果需要对输入波形进行整形的话可以使能此位。此位为 0 的时候禁止迟滞比较器,为 1 的时候使能迟滞比较器。

PUS(bit15:14): 对应图 8.1.4.2 中的 PUS,用来设置上下拉电阻的,一共有四种选项可以选择,如表 8.1.4.1 所示:

表 8.1.4.1 上下拉设置

PUE(bit13): 图 8.1.4.2 没有给出来,当 IO 作为输入的时候,这个位用来设置 IO 使用上下拉还是状态保持器。当为 0 的时候使用状态保持器,当为 1 的时候使用上下拉。状态保持器在IO 作为输入的时候才有用,顾名思义,就是当外部电路断电以后此 IO 口可以保持住以前的状态。

PKE(bit12): 对应图 8.1.4.2 中的 PKE,此位用来使能或者禁止上下拉/状态保持器功能,为0 时禁止上下拉/状态保持器,为 1 时使能上下拉和状态保持器。

ODE(bit11):对应图 8.1.4.2 中的 ODE,当 IO 作为输出的时候,此位用来禁止或者使能开路输出,此位为 0 的时候禁止开路输出, 当此位为 1 的时候就使能开路输出功能。

SPEED(bit7:6): 对应图 8.1.4.2 中的 SPEED,当 IO 用作输出的时候,此位用来设置 IO 速度,设置如表 8.1.4.2 所示:

表 8.1.4.2 速度配置

DSE(bit5:3):对应图 8.1.4.2 中的 DSE,当 IO 用作输出的时候用来设置 IO 的驱动能力,总共有 8 个可选选项,如表 8.1.4.3 所示:

表 8.1.4.3 驱动能力设置

SRE(bit0): 对应图 8.1.4.2 中的 SRE,设置压摆率,当此位为 0 的时候是低压摆率,当为 1的时候是高压摆率。这里的压摆率就是 IO 电平跳变所需要的时间,比如从 0 到 1 需要多少时间,时间越小波形就越陡,说明压摆率越高;反之,时间越多波形就越缓,压摆率就越低。如果你的产品要过 EMC 的话那就可以使用小的压摆率,因为波形缓和,如果你当前所使用的 IO做高速通信的话就可以使用高压摆率。

可以看出寄存器 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 是用来配置 GPIO1_IO00 的,包括速度设置、驱动能力设置、压摆率设置等等。

8.1.5 I.MX6U GPIO 配置

IOMUXC_SW_MUX_CTL_PAD_XX_XX 和 IOMUXC_SW_PAD_CTL_PAD_XX_XX 这两种寄存器都是配置 IO 的,注意是 IO!不是 GPIO 是一个 IO 众多复用功能中的一种。

如果我们要用 GPIO1_IO00 来点个灯、作为按键输入啥的就是使用其 GPIO(通用输入输出)的功能。将其复用为 GPIO 以后还需要对其 GPIO 的功能进行配置,关于 I.MX6U 的 GPIO 请参考《IMX6UL 参考手册》的第 26

章“Chapter 26 General Purpose Input/Ouput(GPIO)”, GPIO 结构如图 8.1.5.1 所示:

图 8.1.5.1 GPIO 结构图

在 图 8.1.5.1 的 左 下 角 的 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 个寄存器。

1、DR 寄存器:此寄存器是数据寄存器,DR 寄存器,此寄存器是数据寄存器:

此寄存器是 32 位的,一个 GPIO 组最大只有 32 个 IO,因此 DR 寄存器中的每个位都对应一个 GPIO。

GPIO 被配置为输出功能:向指定的位写入数据那么相应的 IO 就会输出相应的高低电平,比如要设置 GPIO1_IO00 输出高电平,那么就应该设置 GPIO1.DR=1;

配置为输入模式:此寄存器就保存着对应 IO 的电平值,每个位对对应一个 GPIO,例如,当 GPIO1_IO00 这个引脚接地的话,那么 GPIO1.DR 的 bit0 就是 0。

2、GDIR 寄存器:这是方向寄存器,用来设置某个 GPIO 的工作方向的,即输入/输出, GDIR 寄存器结构如图 8.1.5.3 所示:

图 8.1.5.3 GDIR 寄存器

GDIR 寄存器也是 32 位的,每个 IO 对应一个位,如果要设置 GPIO 为输入设置相应的位为 0,如果要设置为输出就设置为 1。比如要设置 GPIO1_IO00 为输入,那么 GPIO1.GDIR=0;

3、PSR 寄存器:这是 GPIO 状态寄存器

图 8.1.5.4 PSR 状态寄存器

PSR 寄存器也是 32 位的,每个 IO 对应一个位,读取相应的位即可获取对应的 GPIO 的状态,也就是 GPIO 的高低电平值。功能和输入状态下的 DR 寄存器一样。

3、ICR1和ICR2这两个寄存器:都是中断控制寄存器

ICR1用于配置低16个GPIO,ICR2 用于配置高 16 个 GPIO, ICR1 寄存器如图 8.1.5.5 所示:

图 8.1.5.5 ICR1 寄存器

ICR1 用于 IO0~15 的配置, ICR2 用于 IO16~31 的配置。 ICR1 寄存器中一个 GPIO 用两个位,这两个位用来配置中断的触发方式,和 STM32 的中断很类似,可配置的选线如表 8.1.5.1所示:

表 8.1.5.1 中断触发配置

以GPIO1_IO15为例,如果要设置GPIO1_IO15为上升沿触发中断,那么GPIO1.ICR1=2 led.dis clean: rm -rf *.o led.bin led.elf led.dis

创建好 Makefile 以后我们就只需要执行一次“make”命令即可完成编译,如下图所示:

要清理工程的话执行“make clean”即可,如下图所示:

8.4.3 代码烧写

STM32 等其他的单片机的时候,编译完代码以后可以直接通过 MDK 或者 IAR下载到内部的 flash 中。但是 I.MX6U 虽然内部有 96K 的 ROM,但是这 96K 的 ROM 是 NXP自己用的,不向用户开放。所以相当于说 I.MX6U 是没有内部 flash ,I.MX6U 支持从外置的 NOR Flash、 NAND Flash、 SD/EMMC、 SPI NOR Flash和 QSPI Flash 这些存储介质中启动,所以我们可以将代码烧写到这些存储介质中。编译出来的可执行文件是怎么存放到 SD 中的,存放的位置是什么?这个 NXP 是有详细规定的!必须按照 NXP 的规定来将代码烧写到 SD 卡中,否则代码是绝对运行不起来的。《IMX6UL 参考手册》的第 8 章“Chapter 8 System Boot”就是专门讲解 I.MX6U 启动。正点原子专门编写了一个软件来将编译出来的.bin 文件烧写到 SD 卡中,这个软件叫做imxdownload, imxdownlaod 只能在 Ubuntu 下使用,使用步骤如下:

1、将 imxdownload 拷贝到工程根目录下

与 led.bin 处于同一个文件夹下,要不然烧写会失败:

2、给予 imxdownload 可执行权限、

imxdownload 从 Windows 下复制到 Ubuntu 中以后, imxdownload 默认是没有可执行权限的。我们需要给予 imxdownload 可执行权限,执行

chmod +x imxdownload

3、确定要烧写的 SD 卡

准备一张新的 SD(TF)卡,确保 SD 卡里面没有数据,因为我们在烧写代码的时候可能会格式化 SD 卡。

Ubuntu 下所有的设备文件都在目录“/dev”里面,所以插上 SD 卡以后也会出现在“/dev”里面,其中存储设备都是以“/dev/sd”开头。当把SD卡插到电脑后会弹出如下界面,选择如下,将SD卡挂载到了 Ubuntu 系统中,而不是 Windows下(如果默认挂载到Windos下,可以在Vmware的左上角 虚拟机 -> 可移动设备(D)-> 相应设备名 -> 连接)

输入如下命令看可以看到SD卡已挂载到了Ubuntu下:

ls /dev/sd*

其中插上SD卡后多出来了/dev/sda /dev/sda1(名字可能不太一样),其中/dev/sda是SD卡,/dev/sda1是它的一个分区,确定好SD 卡以后我们就可以使用软件 imxdownload 向 SD 卡烧写 led.bin 文件了。

4、向 SD 卡烧写 bin 文件

使用 imxdownload 向 SD 卡烧写 led.bin 文件,命令格式如下:

./imxdownload

其中.bin 就是要烧写的.bin 文件, SD Card 就是你要烧写的 SD 卡,比如我的电脑使用如下命令烧写 led.bin 到/dev/sdd 中:

./imxdownload led.bin /dev/sdb //不能烧写到/dev/sda 或 sda1 设备里面!那是系统磁盘

烧写的过程中可能会让你输入密码,输入你的 Ubuntu 密码即可完成烧写,烧写过程如下图:

如果这个烧写速度大于几十 MB/s、甚至几百 MB/s 那么肯定是烧写失败了!解决方法就是重新插拔 SD 卡,一般出现这种情况,重新插拔 SD 卡基本没啥用,只有重启Ubuntu。

烧写完成以后会在当前工程目录下生成一个 load.imx 的文件,如下图所示:

load.imx 这个文件就是软件 imxdownload 根据 NXP 官方启动方式介绍的内容,在 led.bin 文件前面添加了一些数据头以后生成的。最终烧写到 SD 卡里面的就是这个 load.imx 文件,而非led.bin。

8.4.4 代码验证

代码已经烧写到了 SD 卡中了,接下来就是将 SD 卡插到开发板的 SD 卡槽中,然后设置拨码开关为 SD 卡启动,拨码开关设置如下图所示:

设置好以后按一下开发板的复位键,如果代码运行正常的话 LED0 就会被点亮。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3