【ARM】按鍵·查詢式控制led燈·fs2410

開發環境


    •    硬件平臺:FS2410

    •    主機:Ubuntu 12.04 LTS



LED燈原理圖


按鍵原理圖



按鍵的接線資源


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爲輸出)


按鍵方面涉及到寄存器配置(設置相關寄存器輸入輸出)




精簡原理圖



程序源代碼


//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




編譯



OK,生成 led_key.bin文件了



下載執行



   OK,運行成功!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章