GPIO

来源:互联网 发布:淘宝网上批发市场 编辑:程序博客网 时间:2024/06/06 06:43

好记性不如烂笔头啊,有时间还是要系统性的整理下学过的东西, 我想做做笔记对自己总是有好处的吧。

目的:一个按键控制一个led灯。

2

2

从图中我们可以看到要点亮led,则对应的芯片管脚要置为低电平,ENIT0、ENIT2、ENIT11是接3.3v的电压, 按下时管脚被被拉低。

知道了硬件知识,再参考手册就可以编程了。

其中控制led的管脚为GPF4、GPF5、GPF6。连接按键的管脚为GPF0 GPF2 GPG3(这个要看原理图,没贴出来)

控制led灯的亮灭,就要控制管脚为高电平或者为低电平那么我们要配置管脚为输入输出等模式,并且往相应的寄存器写0 or 1 设为高电平或者为低电平。

代码如下:

/*根据手册我们设置gpf  的控制寄存器和数据寄存器的地址*/
#define GPFCON  (*(volatile unsigned long *)0x56000050)
#define GPFDAT  (*(volatile unsigned long *)0x56000054)

/*根据手册我们设置gpf  的控制寄存器和数据寄存器的地址*/
#define GPGCON  (*(volatile unsigned long *)0x56000060)
#define GPGDAT  (*(volatile unsigned long *)0x56000064)

/*
 *  LED1,LED2,LED4对应GPF4、GPF5、GPF6
 *  将其设置为输出模式(控制寄存器的初始值Reset Value 0X0)
 */

#define GPF4  (1 << (2*4))
#define GPF5  (1 << (2*5))
#define GPF6  (1 << (2*6))
/*清除*/
#define GPF4_CLEAN (3 << (2*4))
#define GPF5_CLEAN (3 << (2*5))
#define GPF6_CLEAN (3 << (2*6))

/*
 *  S2,S3,S4对应GPF0、GPF2、GPG3
 *  将其设置为输入模式
 */
#define GPF0   (0 << (2*0))
#define GPF2   (0 << (2*2))
#define GPG3   (0 << (2*3))
/*清除*/
#define GPF0_CLEAN    (3 << (2*0))
#define GPF2_CLEAN    (3 << (2*2))
#define GPG3_CLEAN    (3 << (2*3))

int main(int argc, char **argv)
{
    unsigned long cDate;
   //led output mod
   GPFCON = GPFCON & (~ (GPF4_CLEAN ) | (GPF5_CLEAN ) | (GPF6_CLEAN ));
   GPFCON = GPFCON  | (GPF4 | GPF5 | GPF6);

   //key input mod
   GPFCON =  GPFCON & ( ~(GPF0_CLEAN) | (GPF2_CLEAN) );
   GPFCON = GPFCON | (GPF0 | GPF2);
   GPGCON = GPGCON & (~GPG3_CLEAN);
   GPGCON = GPGCON | GPG3;

   while(1)
   {
      cDate = GPFDAT;  
       if(cDate & (1<<0))  // s2 down
       {
           GPFDAT = GPFDAT | (1 << 4);   //GPF4 output 1 灯灭
}
else
{
         GPFDAT = GPFDAT & (~(1 << 4));  //灯亮 注意这里是&上0
}

 if(cDate & (1 << 2))  // s3 down
       {
           GPFDAT = GPFDAT | (1 << 5);   //GPF5 output 1 灯灭
}
else
{
         GPFDAT = GPFDAT & (~(1 << 5));  //灯亮
}

cDate =  GPGDAT;

if(cDate & (1 << 3))  // s4 down
       {
           GPFDAT = GPGDAT | (1 << 6);   //GPF6 output 1 灯灭
}
else
{
         GPFDAT = GPGDAT & (~(1 << 6));  //灯亮
}  
   }
return 0;
}


makefile文件内容如下:

key_led.bin : crt0.S  key_led.c
arm-linux-gcc -g -c -o crt0.o crt0.S
arm-linux-gcc -g -c -o key_led.o key_led.c
arm-linux-ld -Ttext 0x0000000 -g  crt0.o key_led.o -o key_led_elf
arm-linux-objcopy -O binary -S key_led_elf key_led.bin
arm-linux-objdump -D -m arm  key_led_elf > key_led.dis
clean:
rm -f   key_led.dis key_led.bin key_led_elf *.o


启动文件

.text
.global _start
_start:
            ldr     r0, =0x53000000     @ WATCHDOG寄存器地址
            mov     r1, #0x0                     
            str   r1, [r0]                 @ 写入0,禁止WATCHDOG,否则CPU会不断重启
            
            ldr     sp, =1024*4   @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
                                               @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
            bl      main                @ 调用C程序中的main函数
halt_loop:
            b       halt_loop



0 0
原创粉丝点击