前言
调试UBOOT使用LED闪烁去标注程序运行到哪里是一个不错的方法,在移植UBOOT的时候,没有打印,所以需要添加LED闪烁汇编,网上资料不知道为什么这么少,成功之后需要记录。
芯片:IMX6U5D
原理图
LED灯 D6 ,原理图可以知道,需要控制GPIO引脚KEY_ROW6,高电平点亮,低电平熄灭。
引脚KEY_ROW6实际上的GPIO_2
查看芯片手册
- 查找官方芯片手册,IMX6SDLRM,该手册可以去官网下载。
可以看到,GPIO_2 属于GPIO1_IO2 - GPIO配置流程:
- 按照流程第一步,配置 IOMUX, 选择为GPIO模式;
配置上图寄存器0-3位为101,选择GPIO1_IO2; - 配置GPIO为输出,寄存器为GPIO_GDIR
寄存器共32位,每一位代表一个IO口,我们使用GPIO2,所以配置2BIT,0位输入,1为输出; - 配置数据寄存器,输出高低电平
和方向寄存器一样,每一位代表一个IO口,我们需要2BIT,高电平赋1,清零2BIT输出低电平;
编写程序,点亮LED灯
如图,为寄存器地址;
/*configure IOMUX to select GPIO mode */
ldr r0, =0x20e0224 // IOMUX寄存器地址放入R0寄存器
mov r1,#0x05 // 5值放入 R1
str r1,[r0] // 将数值 5 写入R0寄存器,也就是IOMUX寄存器里写5,配置GPIO2
/*Configure GPIO direction register to output GPIO_GDIR[2] bit 1*/
ldr r0, =0x209c004 // 把GPIO1_GDIR寄存器地址写入R0
mov r1, #1<<2 // (1 << 2) 写入 r1
str r1,[r0] // 把r1 中的值写入 r0,即把(1 << 2) 写入寄存器GPIO1_GDIR,
设置GPIO2为输出。此程序比较简单,其他位同时也被赋值为0,暂时可以不去管,只要点亮即可
loop: // 开始循环闪烁
/* Write value to data register GPIO_DR*/
ldr r0, =0x209c000 // 以下三行是往寄存器 GPIO1_DR写(1 <<2 ),即2BIT赋1,设置GPIO2输出高电平,LED亮
mov r1, #1<<2
str r1,[r0]
ldr r2, =0xfffff // 以下6行是延时函数,一开始测试发现灯不亮,所以把函数重复放在这里以及下面,减少为题程度,也可以单独写一个函数,跳转过去;
ldr r1, =0
delayloop:
subs r2,r2,#1 // r2寄存器中的值 0xffffff 每次减1,然后再放回 r2寄存器中
cmp r2,r1 // 比较r2与r1寄存器的值,即比较r2与0的值
bne delayloop // 如果r2的值不为0 ,则继续返回delayloop进行循环,否则,往下执行
/*led off*/
ldr r0, =0x209c000 // 以下三行是往寄存器 GPIO1_DR写(1 <<2 ),即2BIT赋1,设置GPIO2输出 低电平,LED灭
mov r1, #0<<2
str r1,[r0]
ldr r2, =0xfffff // 以下是延时函数,可以将其写成一个函数, bl delay 跳转即可
ldr r1, =0
delayloop1:
subs r2,r2,#1
cmp r2,r1
bne delayloop1
b loop // 返回到LOOP,循环闪烁
总结
- 一开始灯没有闪烁,调试很久,才发现延时函数,r2赋值过小,运行过快,LED一直是亮的,后来修改值大,才成功的;
- LED灯可以闪烁,这样就可以再串口还没有初始化,程序还没有进入C程序之前,进行调试,查看程序卡在哪一步,然后进行修改即可。