GPBCON是用來設置輸入輸出屬性的,也就是說,你不是要控制LED嗎?現在你知道了LED的引腳有GPB0,GPB1,而GPBCON又是控制這些引腳的屬性,那麼現在我們要控制它閃爍就要設置這些引腳的屬性爲輸出。那麼如何設置呢?我們的引腳是GPB0,GPB1,而GPBCON是兩位控制一個引腳,所以應該是0101(這裏手冊上說的很清楚),GPBCON寄存器的低22位都是用來控制引腳的屬性,其中每兩位控制一個引腳,如[1:0]來控制GPB0也就是第0個引腳,[21:20]來控制GPB10也就是第11個引腳,而在板子上面每個LED一般都有兩個引腳,所以兩個引腳都要設置,設置爲00則表示輸入狀態,01表示輸出狀態(一般是高位在前,如GPB0[1:0]也就是第1位爲0,第0位爲1),10爲特殊功能,11保留待用.
即GPBCON=0X5(0101二進制換爲16進制就是5)
GPBDAT是用來讀寫引腳的,這個更重要了。我們要控制第一個,第二個引腳。
#define LED3_ON() (GPBDAT &= ~(0x1)) 當LED3亮的時候,把GPBDAT的最後一位置0 (GPB0是最後一位撒)
#define LED4_ON() (GPBDAT &= ~(0x2)) 當LED4亮的時候,把GPBDAT的倒數第二位置0 (GPB1倒。第二撒)
#define LED3_OFF() (GPBDAT |= (0x1))當LED3 滅的時候,把GPBDAT的最後一位置1 (GPB0是最後一位撒)
#define LED4_OFF() (GPBDAT |= (0x2))當LED4 滅的時候,把GPBDAT的倒數第二位置1 (GPB1倒數第二撒)
GPBUP是端口上拉寄存器 端口上拉寄存器控制着每個端口組的上拉寄存器的使能或禁止,當對應bit爲0,這個引腳的上拉寄存器是允許的,當爲1時,上拉寄存器是禁止的。
這裏我們把它禁止掉GPBUP=0xffff;
說到這裏,應該差不多了。可以亮,可以滅,但是要閃爍,我們必須還需要一個延時程序。
delay:
sub r0,r0,#1
cmp r0,#0x0
bne delay
mov pc,lr
現在作爲一個LED閃爍的必要準備工作已經完成了,下面就是湊成一個完整的程序就OK了。
需要兩個程序,一個彙編,一個C文件。
彙編程序用來入口以及那個延時程序,C程序用來處理亮,滅。顯示閃爍效果。
具體代碼如下:led.s
.text
.global _start
ldr sp,=1024*4
.extern main
bl main
.global delay
delay:
sub r0,r0,#1
cmp r0,#0x0
bne delay
mov pc,lr
.end
led.c
extern void delay(int time);
#define GPBCON (*(volatile unsigned *)0x56000010)
#define GPBDAT (*(volatile unsigned *)0x56000014)
#define GPBUP (*(volatile unsigned *)0x56000018)
#define LED3_ON() (GPBDAT &= ~(0x1))
#define LED4_ON() (GPBDAT &= ~(0x2))
#define LED3_OFF() (GPBDAT |= (0x1))
#define LED4_OFF() (GPBDAT |= (0x2))
void Main()
{
GPBCON=0x5;
[size=-1]GPBUP =0xffff;
while(1)
{
LED3_ON();
delay(0xfffff);
LED4_ON();
delay(0xfffff);
LED3_OFF() ;
delay(0xfffff);
LED4_OFF();
delay(0xfffff);
}
}
累死我了,不知道打錯沒,若有錯誤請指出啊。因爲我上網時用一個機器,寫程序是另一個機器(不能上網,因爲盜版的問題),所以代碼不能拷貝。有錯誤的地方望見諒啊。。
末了,寫寫在linux上怎麼編譯吧,因爲開始在這裏我還卡了一下,所以覺得應該有必要寫出來(還是隻是我比較弱,大家早就知道了啊)
arm-linux-gcc -g -c -o led.o led.s
arm-linux-gcc -g -c -o led_on.o led.c
arm-linux-ld -Ttext 0x0000000 -g led.o led_on.o -o led_on_c.o
arm-linux-objcopy -O binary -S led_on_c.o led_on (注意這裏O跟S是大寫)
如有下面一段代碼:
#define GPBCON (*(volatile unsingned long *)0x56000010)
#define GPBDAT (*(volatile unsingned long *)0x56000014)
#define GPB5_out (1<<(5*2))
GPBCON=GPB5_out; //GPB5引腳設置爲輸出
GPBDAT&=~(1<<5); //GPB5輸出低電平
可以看到第三句,因爲GPB5也就是第5個引腳,GPBCON對應控制它的也就是[11:10],所以需要將0x1左移10位也就是得到第11,10位爲01,看到第5句,GPBDAT寄存器的低11位也是分別用來對應11個引腳的數值狀態,爲0則表示LED滅,爲1則表示LED亮,所以需要將0x1左移5位然後取反,然後和GPBDAT相與,這樣只會將第5位置爲0.