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的操作,这是操作硬件的基本技能。

  • 相关阅读:
    ExecuteScalar requires the command to have a transaction when the connection assigned to the command is in a pending
    如何从vss中分离程序
    String or binary data would be truncated
    the pop3 service failed to retrieve authentication type and cannot continue
    The POP3 service failed to start because
    IIS Error he system cannot find the file specified _找不到页面
    pku2575Jolly Jumpers
    pku2940Wine Trading in Gergovia
    pku3219二项式系数
    pku1029false coin
  • 原文地址:https://www.cnblogs.com/Ye-Jason/p/7353691.html
Copyright © 2011-2022 走看看