【嵌入式Linux+ARM】GPIO操作


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

 

[cpp]  view plain  copy
 print?在CODE上查看代碼片派生到我的代碼片
  1. .text  
  2. .global _start  
  3. _start:  
  4.     LDR R0, =0x56000050    //GPFCON寄存器地址  
  5.     MOV R1, #0x00001500    //見技術手冊相應的配置,一般01為輸出引腳  
  6.     STR R1, [R0]           //設置為輸出  
  7.   
  8.     LDR R0, =0x56000054    //GPFDAT寄存器  
  9.     MOV R1, #0x00000000  
  10.     STR R1, [R0]           //往GPFDAT寄存器寫值  
  11. MAIN_LOOP:  
  12.     B MAIN_LOOP            //循環等待  

Makefile:

 

 

[cpp]  view plain  copy
 print?在CODE上查看代碼片派生到我的代碼片
  1. led_on.bin:led_on.S  
  2.     arm-linux-gcc -g -c led_on.S -o led_on.o  
  3.     arm-linux-ld -Ttext 0x00000000 -g led_on.o -o led_on_elf    //-Ttext表示設置連接地址  
  4.     arm-linux-objcopy -O binary -S led_on_elf led_on.bin        //把elf文件轉換為.bin文件  
  5. clean:  
  6.     rm -rf *.bin *.o *elf   

 

>>使用C語言實現點燈

使用c語言來寫,需要一個啟動文件,可以用來關閉看門口,設置堆棧等。

crt0.S

 

[cpp]  view plain  copy
 print?在CODE上查看代碼片派生到我的代碼片
  1. .text  
  2. .global _begin  
  3. _begin:  
  4.     LDR R0, =0x53000000    //看門狗寄存器地址  
  5.     MOV R1, #0x00000000    //寫0禁止看門狗  
  6.     STR R1, [R0]  
  7.       
  8.     LDR SP, =1024*4        //設置堆棧,注意不能大於4K,因為現在可用的SRAM空間只有4K  
  9.     BL main                //調用main函數,最后注意,匯編語言大小寫無所謂的  
  10. _LOOP:  
  11.     B _LOOP  

 

led_on_c.c

 

[cpp]  view plain  copy
 print?在CODE上查看代碼片派生到我的代碼片
  1. #define GPFCON *(volatile unsigned long *)0x56000050  
  2. #define GPFDAT *(volatile unsigned long *)0x56000054  
  3.   
  4. int main()  
  5. {  
  6.     GPFCON=0x00001500;//簡單的配置為輸出  
  7.     GPFDAT=0x00000000;//簡單的輸出0,通過上面的原理圖可知,相應的led會亮  
  8.   
  9.     return 0;  
  10. }  

 

Makefile

[cpp]  view plain  copy
 print?在CODE上查看代碼片派生到我的代碼片
  1. led_on_c.bin : crt0.S  led_on_c.c  
  2.     arm-linux-gcc -g -c -o crt0.o crt0.S  
  3.     arm-linux-gcc -g -c -o led_on_c.o led_on_c.c  
  4.     arm-linux-ld -Ttext 0x0000000 -g  crt0.o led_on_c.o -o led_on_c_elf  
  5.     arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin  
  6.     arm-linux-objdump -D -m arm  led_on_c_elf > led_on_c.dis   //把elf文件轉換為反匯編文件  
  7. clean:  
  8.     rm -f led_on_c.dis led_on_c.bin led_on_c_elf *.o  

 

>>使用按鍵+c語言實現點燈

看上面的原理圖,原理就是把按鍵的引腳配置為輸入引腳,以讀取引腳的狀態;

但按鍵被按下時,引腳讀到的是低電平;當按鍵松開時,讀取到高電平;

crt0.S同上;

key_led.c

 

[cpp]  view plain  copy
 print?在CODE上查看代碼片派生到我的代碼片
  1. /* 
  2. GPF4 GPF5 GPF6 --led 
  3.  
  4. GPF0 GPF2 GPG3 --key 
  5. */  
  6.   
  7. #define GPFCON (*(volatile unsigned long *)0x56000050)  
  8. #define GPFDAT (*(volatile unsigned long *)0x56000054)  
  9.   
  10. #define GPGCON (*(volatile unsigned long *)0x56000060)  
  11. #define GPGDAT (*(volatile unsigned long *)0x56000064)  
  12.   
  13. #define GPF4_out (1<<(4*2))  
  14. #define GPF5_out (1<<(5*2))  
  15. #define GPF6_out (1<<(6*2))  
  16.   
  17. #define GPF4_msk (3<<(4*2))  
  18. #define GPF5_msk (3<<(5*2))  
  19. #define GPF6_msk (3<<(6*2))  
  20.   
  21. #define GPF0_in (0<<(0*2))  
  22. #define GPF2_in (0<<(2*2))  
  23. #define GPG3_in (0<<(3*2))  
  24.   
  25. #define GPF0_msk (3<<(0*2))  
  26. #define GPF2_msk (3<<(2*2))  
  27. #define GPG3_msk (3<<(3*2))  
  28.   
  29. int main()  
  30. {  
  31.     unsigned long dwDat;  
  32.     //1 output pin   
  33.     GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);  
  34.     GPFCON |=  (GPF4_out | GPF5_out | GPF6_out);  
  35.   
  36.     //input pin  
  37.     GPFCON &= ~(GPF0_msk | GPF2_msk);  
  38.     GPFCON |=  (GPF0_in | GPF2_in);  
  39.     GPGCON &= ~GPG3_msk;  
  40.     GPGCON |=  GPG3_in;  
  41.   
  42.     while(1)  
  43.     {  
  44.         dwDat = GPFDAT;  
  45.         if(dwDat & (1<<0))  
  46.             GPFDAT |= (1<<4);  
  47.         else  
  48.             GPFDAT &= ~(1<<4);//light  
  49.   
  50.         if(dwDat & (1<<2))  
  51.             GPFDAT |= (1<<5);  
  52.         else  
  53.             GPFDAT &= ~(1<<5);  
  54.   
  55.         dwDat = GPGDAT;   
  56.         if(dwDat & (1<<3))  
  57.             GPFDAT |= (1<<6);  
  58.         else  
  59.             GPFDAT &= ~(1<<6);  
  60.     }  
  61.   
  62.     return 0;  
  63. }  

Makefile相應的修改即可;

 

上面的程序編譯都會得到bin文件,我們把它燒錄進nand flash中即可,燒錄可以使用工具,也可以通過固化在nor flash中的Uboot來燒錄,方法很多,燒錄后,上電,2440CPU會自動把nand flash前4k的內容,拷貝到2440片內4k的SRAM中運行,這塊內存俗稱stepping stone區。

 

 

 

注:原創文章,轉載請注明出處:http://blog.csdn.net/scottly1/article/details/38960309


免責聲明!

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



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