1.GPIO介紹
GPIO(general purpose i/o ports)意思為通用輸入/輸出端口,通俗的說就是一些引腳。
我們可以通過它們輸出高低電平 或 讀入引腳的狀態。
s3c2440中有130個I/O端口,分為A~J共9組,GPA、GPB、..... GPJ
2.GPIO寄存器
既然要操作GPIO,必須對相應的寄存器進行操作,2440中gpio寄存器有:
GPxCON——選擇引腳功能(輸入、輸出、保留等)
GPxDAT——用來讀寫引腳
GPcUP ——某一位是1時,相應的引腳無內部上拉電阻;為0時,有內部上拉電阻
3.原理圖
LED:
按鍵:
4.實驗代碼:
>>使用匯編語言實現點燈:
led_on.S
- .text
- .global _start
- _start:
- LDR R0, =0x56000050 //GPFCON寄存器地址
- MOV R1, #0x00001500 //見技術手冊相應的配置,一般01為輸出引腳
- STR R1, [R0] //設置為輸出
- LDR R0, =0x56000054 //GPFDAT寄存器
- MOV R1, #0x00000000
- STR R1, [R0] //往GPFDAT寄存器寫值
- MAIN_LOOP:
- B MAIN_LOOP //循環等待
Makefile:
- led_on.bin:led_on.S
- arm-linux-gcc -g -c led_on.S -o led_on.o
- arm-linux-ld -Ttext 0x00000000 -g led_on.o -o led_on_elf //-Ttext表示設置連接地址
- arm-linux-objcopy -O binary -S led_on_elf led_on.bin //把elf文件轉換為.bin文件
- clean:
- rm -rf *.bin *.o *elf
>>使用C語言實現點燈
使用c語言來寫,需要一個啟動文件,可以用來關閉看門口,設置堆棧等。
crt0.S
- .text
- .global _begin
- _begin:
- LDR R0, =0x53000000 //看門狗寄存器地址
- MOV R1, #0x00000000 //寫0禁止看門狗
- STR R1, [R0]
- LDR SP, =1024*4 //設置堆棧,注意不能大於4K,因為現在可用的SRAM空間只有4K
- BL main //調用main函數,最后注意,匯編語言大小寫無所謂的
- _LOOP:
- B _LOOP
led_on_c.c
- #define GPFCON *(volatile unsigned long *)0x56000050
- #define GPFDAT *(volatile unsigned long *)0x56000054
- int main()
- {
- GPFCON=0x00001500;//簡單的配置為輸出
- GPFDAT=0x00000000;//簡單的輸出0,通過上面的原理圖可知,相應的led會亮
- return 0;
- }
Makefile
- led_on_c.bin : crt0.S led_on_c.c
- arm-linux-gcc -g -c -o crt0.o crt0.S
- arm-linux-gcc -g -c -o led_on_c.o led_on_c.c
- arm-linux-ld -Ttext 0x0000000 -g crt0.o led_on_c.o -o led_on_c_elf
- arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin
- arm-linux-objdump -D -m arm led_on_c_elf > led_on_c.dis //把elf文件轉換為反匯編文件
- clean:
- rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o
>>使用按鍵+c語言實現點燈
看上面的原理圖,原理就是把按鍵的引腳配置為輸入引腳,以讀取引腳的狀態;
但按鍵被按下時,引腳讀到的是低電平;當按鍵松開時,讀取到高電平;
crt0.S同上;
key_led.c
- /*
- GPF4 GPF5 GPF6 --led
- GPF0 GPF2 GPG3 --key
- */
- #define GPFCON (*(volatile unsigned long *)0x56000050)
- #define GPFDAT (*(volatile unsigned long *)0x56000054)
- #define GPGCON (*(volatile unsigned long *)0x56000060)
- #define GPGDAT (*(volatile unsigned long *)0x56000064)
- #define GPF4_out (1<<(4*2))
- #define GPF5_out (1<<(5*2))
- #define GPF6_out (1<<(6*2))
- #define GPF4_msk (3<<(4*2))
- #define GPF5_msk (3<<(5*2))
- #define GPF6_msk (3<<(6*2))
- #define GPF0_in (0<<(0*2))
- #define GPF2_in (0<<(2*2))
- #define GPG3_in (0<<(3*2))
- #define GPF0_msk (3<<(0*2))
- #define GPF2_msk (3<<(2*2))
- #define GPG3_msk (3<<(3*2))
- int main()
- {
- unsigned long dwDat;
- //1 output pin
- GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);
- GPFCON |= (GPF4_out | GPF5_out | GPF6_out);
- //input pin
- GPFCON &= ~(GPF0_msk | GPF2_msk);
- GPFCON |= (GPF0_in | GPF2_in);
- GPGCON &= ~GPG3_msk;
- GPGCON |= GPG3_in;
- while(1)
- {
- dwDat = GPFDAT;
- if(dwDat & (1<<0))
- GPFDAT |= (1<<4);
- else
- GPFDAT &= ~(1<<4);//light
- if(dwDat & (1<<2))
- GPFDAT |= (1<<5);
- else
- GPFDAT &= ~(1<<5);
- dwDat = GPGDAT;
- if(dwDat & (1<<3))
- GPFDAT |= (1<<6);
- else
- GPFDAT &= ~(1<<6);
- }
- return 0;
- }
Makefile相應的修改即可;
上面的程序編譯都會得到bin文件,我們把它燒錄進nand flash中即可,燒錄可以使用工具,也可以通過固化在nor flash中的Uboot來燒錄,方法很多,燒錄后,上電,2440CPU會自動把nand flash前4k的內容,拷貝到2440片內4k的SRAM中運行,這塊內存俗稱stepping stone區。
注:原創文章,轉載請注明出處:http://blog.csdn.net/scottly1/article/details/38960309