一步步點亮LED之匯編點亮LED


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM