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