• 【嵌入式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

    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:

    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

    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

    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

    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

    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

  • 相关阅读:
    闭包的最准确的解释-待翻译
    undefined 和 null 的异同
    Javascript深度克隆一个对象
    产品培训的经验
    JavaScript库开发者们的规则
    IOS ——UI篇—— UITableView的常用属性及代理方法的用法总结
    IOS ——UI篇—— 自定义UITableViewCell的方法
    IOS ——UI篇—— UIScrollView的用法总结
    使用UIKit中的tag属性要注意的
    IOS ——UI篇——UITabBarController的基本用法
  • 原文地址:https://www.cnblogs.com/wanghuaijun/p/6542308.html
Copyright © 2020-2023  润新知