使用汇编语言来编写,了解如何使用汇编语言来初始化 I.MX6U 外设寄存器、了解 I.MX6UL 最基本的 IO 输出功能。
1:使能 GPIO 对应的时钟。
2:设置寄存器 IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置 IO 的复用功能,使其复用为 GPIO 功能。
3:设置寄存器 IOMUXC_SW_PAD_CTL_PAD_XX_XX,设置 IO 的上下拉、速度等等。
4:第2步已经将 IO 复用为了 GPIO 功能,所以需要配置 GPIO,设置输入/输出、是否使用中断、默认输出电平等。
在代码中使能的方式和stm32很相似
我使用的I.MX6U-ALPHA 开发板 ,在开发板中中有一个LED灯,如图所示:
从图中可以看到,LED0 接到了 GPIO_3 上,GPIO_3 就是 GPIO1_IO03,当 GPIO1_IO03输出低电平(0)的时候发光二极管 LED0 就会导通点亮,当 GPIO1_IO03 输出高电平(1)的时候发光二极管 LED0 不会导通,因此 LED0 也就不会点亮。所以 LED0 的亮灭取决于 GPIO1_IO03的输出电平,输出 0 就亮,输出 1 就灭。
因此再配合数据手册,新建一个文件夹1_leds
新建leds.s文件输入以下代码
global _start @全局变量
_start:
/*时能所有外设时钟*/
ldr r0, =0x020c4068 @CCGR0
ldr r1, =0xffffffff @要向CCGR0写入的数据
str r1, [r0] @将0xffffffff写入到CCGR0
ldr r0, =0x020c406c @CCGR1
str r1, [r0]
ldr r0, =0x020c4070 @CCGR2
str r1, [r0]
ldr r0, =0x020c4074 @CCGR3
str r1, [r0]
ldr r0, =0x020c4078 @CCGR4
str r1, [r0]
ldr r0, =0x020c407c @CCGR5
str r1, [r0]
ldr r0, =0x020c4080 @CCGR6
str r1, [r0]
/* 配置 GPIO1_IO03 PIN的复用为GPIO,也就是设置
* IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03=5
* IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器地址为0x020e0068
*/
ldr r0, =0x020e0068 @IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
ldr r1, =0x5 @要向IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03写入的数据
str r1, [r0] @将5写入到IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03中
/* 配置GPIO1_IO03的电气属性 也就是寄存器:
* IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
* IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03寄存器地址为0x020e02f4
*
* bit0: 0 低速率
* bit5:3 110 R0/6驱动能力
* bit7:6 10 100MH速度
* bit11 0 关闭开漏输出
* bit12 1 使能pull/keeper
* bit13 0 kepper
* bit15:14 00 100K下拉
* bit16 0 关闭hys
* 10b0
*/
ldr r0, =0x020e02f4
ldr r1, =0x10b0
str r1, [r0]
/* 设置GPIO
* 设置GPIO_GDIR寄存器,设置GPIO1_IO03为输出
* GPIO1_GDIR寄存器地址为0x0209c004,设置GPIO1_GDIR的bit3为1
* 也就是设置GPIO1_IO03为输出
*/
ldr r0, =0x0209c004
ldr r1, =0x08
str r1, [r0]
/* 打开LED,也就是设置GPIO_IO03为0
* GPIO1_DR寄存器地址为0x0209c000
*/
ldr r0, =0x0209c000
ldr r0, =0
str r1, [r0]
loop:
b loop @通过 b 指令,CPU 重复不断的跳到 loop 函数执行,进入一个死循环。
新建一个Makefile文件,此作用为编译代码,以及删除掉无需用到的文件
led.bin : leds.s
arm-linux-gnueabihf-gcc -g -c leds.s -o led.o
arm-linux-gnueabihf-ld -Ttext 0x87800000 led.o -o led.elf
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
arm-linux-gnueabihf-objdump -D led.elf > led.dis
代码烧写,I.MX6U 支持从外置的 NOR Flash、NAND Flash、SD/EMMC、SPI NOR Flash和 QSPI Flash 这些存储介质中启动,我们在调试裸机和 Uboot 的时候是将代码下载到 SD 中,因为方便嘛,当调试完成以后量产的时候要将裸机或者 Uboot 烧写到 SPI NOR Flash、EMMC、NAND 等这些存储介质中的。
那么我们编译出来的bin文件也不是直接复制粘贴在SD中,而是要通过原子他家专门编写的一个软件来将将编译出来的.bin 文件烧写到 SD 卡中,这个软件叫做“imxdownload”首先我们也需要将imxdownload 拷贝到工程根目录下,并且需要给与这个软件可执行权限,方法如下:
使用命令“chmod”给与权限,然后我们可以看到目录下的软件从白色变成绿色
然后,准备一张SD卡,这里使用的卡必须是里面没有数据,要不然烧写会失败,所以我们在烧写代码的时候要格式化SD卡
然后此时才可以向SD卡烧录bin文件
使用 imxdownload 向 SD 卡烧写 led.bin 文件,命令格式如下:
./imxdownload <.bin file> <SD Card>
因为我这里SD卡名称为/dev/sdb,所以这样子:
./imxdownload led.bin /dev/sdb,
回车后看到输出内容:
之后我们能看到,目录下生成了一个load.imx文件
oad.imx 这个文件就是软件 imxdownload 根据 NXP 官方启动方式介绍的内容,在 led.bin 文件前面添加了一些数据头以后生成的。最终烧写到 SD 卡里面的就是这个 load.imx 文件,而非led.bin。
此时此刻,代码已经烧写到了 SD 卡中了
我们先上电看一下,不插SD卡的时候是怎么样的,右下角只有蓝灯显示:
插上SD卡:
记得要把左下角的开关设置成以SD卡启动,那就是1000 0010:
断电重启后,就会发现右下角的红灯亮起来了,IO口驱动成功: