开发环境


    •    硬件平台:FS2410

    •    主机:Ubuntu 12.04 LTS



LED灯原理图

【ARM】按键·查询式控制led灯·fs2410_第1张图片


按键原理图

【ARM】按键·查询式控制led灯·fs2410_第2张图片



按键的接线资源


KSCAN0 -> GPE11    KSCAN1 -> GPG6     KSCAN2 -> GPE13      KSCAN3 -> GPG2
   EINT0  -> GPF0     EINT2  -> GPF2     EINT11 -> GPG3       EINT19 -> GPG11



程序主要原理


这里实现对 K1,K2,K3,K4 这四个键的查询。

   主要涉及到K1,K2, K3, K4这四个按键,要用查询的方式进行判断哪个键被按下去了,因此:

  • EINT11, EINT19设置为输入,用于读取;

  • KSCAN0KSCAN1KSACAN2,设置为输出,并分别设置为0,1,11,0,11,1,0三种情况,这样可用于区分K1、K2、K3中哪个键按下去。

   例如先让KSCAN0~2 = 011,那么K1被按下时,EINT19才会变为低电平,这时K2按下时,EINT19不会变低,这样就区分了按键K1和K2,区分其它按键原理一样。



寄存器配置


有关LED的寄存器的配置:(设置GPF4-GPF7为输出)

【ARM】按键·查询式控制led灯·fs2410_第3张图片


按键方面涉及到寄存器配置(设置相关寄存器输入输出)

【ARM】按键·查询式控制led灯·fs2410_第4张图片

【ARM】按键·查询式控制led灯·fs2410_第5张图片




精简原理图

【ARM】按键·查询式控制led灯·fs2410_第6张图片



程序源代码


//led_key.c

#include "2410addr.h"
                                                                                                                                               
void delay(long long max)      //延迟函数
{
    for(; max > 0; max--);
                                                                                                                                               
}
                                                                                                                                               
int main(void)
{
    int read_value;
                                                                                                                                               
    rGPFCON = rGPFCON & (~(0xff) << 8) | (0x55 << 8);     //设置4个LED灯为输出(GPF4-GPF7输出)
    rGPFDAT |= (0xf << 4);       //先将4个灯都熄灭掉
                                                                                                                                               
    rGPGCON = (0 << 7) | (1 << 12) | (0 << 23);       //GPG3, GPG11 输入,GPG6, GPE11, GPE13输出
    rGPECON =  (1 << 22) | (1 << 26);
                                                                                                                                               
    while(1)
    {
        rGPEDAT &= (0 << 11);      //将GPE11置0,同时将GPE13和GPG6置1
        rGPEDAT |= (1 << 13);
        rGPGDAT |= (1 << 6);
                                                                                                                                               
        read_value = rGPGDAT & 0x808;      //读取GPG11和GPG3的输入值
                                                                                                                                               
        if((read_value & 0x800) == 0)       //判断GPG11输入是否为0,以此判断K1键是否按下
        {
            read_value = 0x800;
            delay(200000);        //按键去抖
                                                                                                                                               
            if((read_value &= rGPGDAT) == 0)
            {
                if((rGPFDAT & (1 << 4)) == 0)      //判断D12是否亮着,如果亮着则熄灭,反之相反
                    rGPFDAT |= (0x1 << 4);
                else
                    rGPFDAT &= (0xe << 4);
            }
        }
        else
        {
            if((read_value & 0x8) == 0)     //判断GPG3输入的值是否为0, 以此K4键是否按下
            {
                read_value = 0x8;
                delay(200000);        //按键去抖
                                                                                                                                               
                if((read_value &= rGPGDAT) == 0)
                {
                    if((rGPFDAT & (0x8 << 4)) == 0)     //判断D9是都亮着,如果亮着则熄灭,反之相反
                        rGPFDAT |= (0x8 << 4);
                    else
                        rGPFDAT &= (0x7 << 4);
                }
            }
        }
                                                                                                                                               
                                                                                                                                               
        rGPEDAT |= (1 << 11);     //将GPE11和GPE13置1,同时将GPG6置0
        rGPEDAT |= (1 << 13);
        rGPGDAT &= (0 << 6);
                                                                                                                                                   
        read_value = rGPGDAT & (0x8 << 8);       //读取GPG11的值
                                                                                                                                                                               
        if(read_value == 0)       //判断GPG11是否输入0,以此判断K2键按下
        {  
            read_value = 0x800; 
            delay(200000);       //按键去抖
                                                                                                                                                                                                                      
            if((read_value &= rGPGDAT) == 0)
            { 
                if((rGPFDAT & (0x2 << 4)) == 0)     //判断D11是否亮着, 如果亮着则熄灭,反之相反
                    rGPFDAT |= (0x2 << 4); 
                else 
                    rGPFDAT &= (0xd << 4); 
            } 
        }
                                                                                                                                               
        rGPEDAT &= (0 << 13);      //将GPE13置0, 同时将GPE11和GPG6置1
        rGPEDAT |= (1 << 11);
        rGPGDAT |= (1 << 6);
                                                                                                                                               
        read_value = rGPGDAT & 0x800;           //读取GPG11的值
                                                                                                                                               
        if(read_value == 0)        //判断GPG11是否为0,以此判断K3键是否按下
        {
            read_value = 0x800;
            delay(200000);      //按键去抖,延迟一段时间
                                                                                                                                               
            if((read_value &= rGPGDAT) == 0)
            {
                if((rGPFDAT & (0x4 << 4)) == 0)      //判断D10是否亮着,如果亮着则熄灭,反之相反
                    rGPFDAT |= (0x4 << 4);
                else
                    rGPFDAT &= (0xb << 4);
            }
        }
    }
                                                                                                                                               
    return 0;
}


//启动文件start.S

.text
.global _start
_start:
#define WATCHDOG 0x53000000
    ldr r0, =WATCHDOG
    mov r1, #0
    str r1, [r0]
                                                                                                                   
    ldr sp, =1024*4
    bl main
                                                                                                                   
loop:
    b loop


//Makefile

led.bin:start.S led_key.c
    arm-linux-gcc -c start.S -o start.o
    arm-linux-gcc -c led_key.c -o led_key.o
    arm-linux-ld -Ttext 0x30008000 start.o led_key.o -o led_key
    arm-linux-objcopy -O binary -S led_key led_key.bin
clean:
    rm -f *.o led_key.bin




编译


【ARM】按键·查询式控制led灯·fs2410_第7张图片


OK,生成 led_key.bin文件了



下载执行


【ARM】按键·查询式控制led灯·fs2410_第8张图片


   OK,运行成功!