zoukankan      html  css  js  c++  java
  • 嵌入式GPIO接口及操作(二)

    目标:C语言实现点亮LED灯

    首先是main函数,并不特殊,它是被系统调用来执行的,main函数结束后要返回调用main函数的地址处,那么裸机程序,没有操作系统做这些工作,就要自己写调用main函数的程序了。
    软件相关的初始化:
    1、设置栈 2、设置main函数返回地址 3、调用main 4、清理工作

    所谓设置栈就是将栈指针SP指向某块内存,在S3C2440中这块内存可以是片内SRAM,这样不用初始化内存了,如果指向SDRAM,那么首先要初始化SDRAM。
    硬件相关的初始化:
    a、关闭看门狗;b、初始化时钟;c、初始化SDRAM等
    软件相关初始化和硬件相关初始化结合一起就是启动文件。

    下面是用C语言写的代码
    这一段代码是汇编语言,作用相当于启动文件,在这里为了简单,在硬件方面初始化只关闭了看门狗,软件方面初始化设置了栈。

    crt.S

    .text  
    .global _start  
    _start:  
                ldr r0,=0x53000000  @看门狗地址  
                mov r1,#0x0  
                str r1,[r0] @写入0,关闭看门狗  
                ldr sp,=1024*4  @设置堆栈,注意不能大于4K  
                  
                bl  main  
    halt_loop:  
                b halt_loop  

    分析这段汇编程序,首先初始化硬件相关的,关闭看门狗,然后设置堆栈,在s3c2440不能大于4K,因为s3c2440片内SRAM只有4K,再然后就是调到main函数,用了bl指令,bl有两个功能,一是跳转,二是设置了返回地址,就是bl    main指令的下一条指令b hail_loop,所以在这里就初始化完返回地址了。
    下面就实现c语言的main函数。

    #define GPFCON  (*(volatile unsigned long *)0x56000050)  
    #define GPFDAT  (*(volatile unsigned long *)0x56000054)  
    int  
    main()  
    {  
        GPFCON = 0x00000100;  
        GPFDAT = 0x00000000;  
          
        return 0;  
    }  

    2、用C语言轮流点亮LED

    #define GPFCON  (*(volatile unsigned long *)0x56000050)  
    #define GPFDAT  (*(volatile unsigned long *)0x56000054)  
    #define GPF4_out ( 1 << 4*2 )  
    #define GPF5_out ( 1 << 5*2 )  
    #define GPF6_out ( 1 << 6*2 )  
    void   
    delay(volatile unsigned long dly)  
    {  
        for(;dly > 0;dly--);  
    }  
    int  
    main()  
    {  
        unsigned i = 1;  
          
        GPFCON = GPF4_out | GPF5_out | GPF6_out;  
        while(1)  
        {  
            GPFDAT = ( ~( i << 4 ) );  
            i *=2;  
            if( i == 8)  
            {  
                i = 1;  
            }  
            delay(30000);  
      
              
        }  
          
          
        return 0;  
    }  

    Makefile

    CFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding  
    led_on.bin:ctr.S main.c  
        arm-linux-gcc $(CFLAGS) -c -o ctr.o ctr.S  
        arm-linux-gcc $(CFLAGS) -c -o main.o main.c  
        arm-linux-ld -Ttext 0x00000000 ctr.o main.o -o led_on.elf  
        arm-linux-objcopy -O binary -S led_on.elf led_on.bin  
        arm-linux-objdump -D -m arm led_on.elf>led_on.dis  
    clean:  
        rm -f led_on.bin led_on.elf *.o led_on.dis  

    3、按键操作

    #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( void )  
    {  
        unsigned long ysdat;  
        GPFCON &= ~( GPF4_msk | GPF5_msk | GPF6_msk );  
        GPFCON |= GPF4_out |GPF5_out | GPF5_out;  
          
        GPFCON &= ~( GPF0_msk | GPF2_msk );  
        GPFCON |= GPF0_in |GPF2_in;  
          
        GPGCON &= ~( GPG3_msk );  
        GPGCON |= GPG3_in;  
          
        while(1)  
        {  
             ysdat = GPFDAT;  
               
             if( ysdat & ( 1 << 0 ) )  
             {  
                GPFDAT |= ( 1 << 4 );           
             }    
             else  
             {  
                GPFDAT &= ~( 1 << 4 );  
             }  
               
             if( ysdat & ( 1 << 2 ) )  
             {  
                GPFDAT |= ( 1 << 5 );           
             }    
             else  
             {  
                GPFDAT &= ~( 1 << 5 );  
             }  
               
             ysdat = GPGDAT;  
               
             if( ysdat & ( 1 << 3 ) )  
             {  
                GPFDAT |= ( 1 << 6 );           
             }    
             else  
             {  
                GPFDAT &= ~( 1 << 6 );  
             }  
               
        }  
          
        return 0;  
    }  

    Makefile

    CFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -ffreestanding  
    led_on.bin:ctr.S main.c  
        arm-linux-gcc $(CFLAGS) -c -o ctr.o ctr.S  
        arm-linux-gcc $(CFLAGS) -c -o main.o main.c  
        arm-linux-ld -Ttext 0x00000000 ctr.o main.o -o led_on.elf  
        arm-linux-objcopy -O binary -S led_on.elf led_on.bin  
        arm-linux-objdump -D -m arm led_on.elf>led_on.dis  
    clean:  
        rm -f led_on.bin led_on.elf *.o led_on.dis  

    通过嵌入式GPIO接口及操作(一)及这篇两个程序的练习,能够掌握对GPIO的操作,这是操作硬件的基本技能。

  • 相关阅读:
    Codeforces Round #610 (Div. 2)C(贪心,思维)
    Educational Codeforces Round 80 (Rated for Div. 2)C(DP)
    BZOJ2190 仪仗队
    BZOJ3613 南园满地堆轻絮
    BZOJ1084 最大子矩阵
    BZOJ1036 树的统计Count
    BZOJ1452 Count
    BZOJ2242 计算器
    BZOJ2705 Longge的问题
    BZOJ1509 逃学的小孩
  • 原文地址:https://www.cnblogs.com/Ye-Jason/p/7353691.html
Copyright © 2011-2022 走看看