GPJ0CON端口一共有8个端口,分别记住:GPJ0_0~GPJ0_7;相关寄存器为GPJ0CON、GPJ0DAT
GPJ0CON寄存器中设置8个引脚的工作模式(32/8=4,每个引脚分到4位,譬如GPJ0_0位bit0~bit3,我们就给=它写入0001得到输出模式)
1、需要控制的引脚:GPJ0_3、GPJ0_4、GPJ0_5低电平亮,高电平灭。
2、GPJ0CON(0xE0200240):控制模式
GPJ0DAT(0xE0200244):控制引脚数据
注意:由于IO与内存统一编址,所以不能直接往寄存器写入值,我们应该用指针的方式访问对应的地址间接写入。
将led灯全部点亮
/* *文件名:led.S *作者:*** *描述:这是我们一步步点亮led灯的第一个led程序 * */ _start: //第一步:把0x11111111写入0xE0200240(GPJOCON)位置 ldr r0, =0x11111111 //从后面的=号可以看出来是伪指令,因为需要编译器来判 ldr r1, =0xE0200240 //定是合法立即数还是非法立即数,一般都是ldr伪指令 str r0, [r1] //把r0中的数写入r1为地址的内存中去 //第二步:把0x0写入0xE0200244(GPJ0DAT) ldr r0, =0x0 ldr r1, =0xE0200244 str r0, [r1] //把0写入r1(0xE0200244)中
b . //写了一个死循环。逐行运行裸机程序直到断电
编译后得到led.bin烧录到裸机中,就可以点亮led。
下面开始改进上述代码
1、增加可读性
由于上述代码可读性较差,过度依赖注释,下面需要改进代码,虽然可能增加代码复杂度,但是可读性增强
(1)运用宏定义,把对应的内存地址和GPIO名字绑定
(2)运用位操作,只亮中间一个灯(位操作便于直观看出哪位改动了)
#define GPJ0C0N 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start _start: //第一步:把0x11111111写入0xE0200240(GPJOCON)位置 ldr r0, =0x11111111 //从后面的=号可以看出来是伪指令,因为需要编译器来判 ldr r1, =GPJ0C0N //定是合法立即数还是非法立即数,一般都是ldr伪指令 str r0, [r1] //把r0中的数写入r1为地址的内存中去 //第二步:把0x0写入0xE0200244(GPJ0DAT) ldr r0, =(0x0)|(1<<3)|(0<<4)|(1<<5) ldr r1, =GPJ0DAT str r0, [r1] //把0写入r1(0xE0200244)中 b . //写了一个死循环。逐行运行裸机程序直到断电
2、led流水灯效果
(1)加入延时代码
(2)加入循环
#define GPJ0C0N 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start _start: //第一步:把0x11111111写入0xE0200240(GPJOCON)位置 ldr r0, =0x11111111 //从后面的=号可以看出来是伪指令,因为需要编译器来判 ldr r1, =GPJ0C0N //定是合法立即数还是非法立即数,一般都是ldr伪指令 str r0, [r1] //把r0中的数写入r1为地址的内存中去 flash: //第二步:闪烁效果 //点亮第一个灯,延时 ldr r0, =(0<<3)|(1<<4)|(1<<5) ldr r1, =GPJ0DAT str r0, [r1] //把0写入r1(0xE0200244)中 bl delay //熄灭,延时 ldr r0, =(1<<3)|(1<<4)|(1<<5) ldr r1, =GPJ0DAT str r0, [r1] //把0写入r1(0xE0200244)中 bl delay //点亮第二个灯,延时 ldr r0, =(1<<3)|(0<<4)|(1<<5) ldr r1, =GPJ0DAT str r0, [r1] //把0写入r1(0xE0200244)中 bl delay //熄灭,延时 ldr r0, =(1<<3)|(1<<4)|(1<<5) ldr r1, =GPJ0DAT str r0, [r1] //把0写入r1(0xE0200244)中 bl delay //点亮第三个灯,延时 ldr r0, =(1<<3)|(1<<4)|(0<<5) ldr r1, =GPJ0DAT str r0, [r1] //把0写入r1(0xE0200244)中 bl delay //熄灭,延时 ldr r0, =(1<<3)|(1<<4)|(1<<5) ldr r1, =GPJ0DAT str r0, [r1] //把0写入r1(0xE0200244)中 bl delay b flash b . //写了一个死循环。逐行运行裸机程序直到断电(由于上一行有循环,这行根本不会执行,也可以删掉)
delay: ldr r2, =900000 ldr r3, =0x0 delay_loop: sub r2, r2, #1 cmp r2, r3 //cmp会影响Z标志位,如果r2=r3则Z等于1,下一句eq就会成立 bne delay_loop mov pc, lr