開發環境linux
硬件平臺:FS2410bash
主機:Ubuntu 12.04 LTS
ide
LED燈原理圖
函數
按鍵原理圖
oop
按鍵的接線資源
spa
KSCAN0 -> GPE11 KSCAN1 -> GPG6 KSCAN2 -> GPE13 KSCAN3 -> GPG2
EINT0 -> GPF0 EINT2 -> GPF2 EINT11 -> GPG3 EINT19 -> GPG11blog
程序主要原理
資源
這裏實現對 K1,K2,K3,K4 這四個鍵的查詢。開發
主要涉及到K1,K2, K3, K4這四個按鍵,要用查詢的方式進行判斷哪一個鍵被按下去了,所以:get
將EINT11, EINT19設置爲輸入,用於讀取;
將KSCAN0,KSCAN1,KSACAN2,設置爲輸出,並分別設置爲0,1,1或1,0,1或1,1,0三種狀況,這樣可用於區分K一、K二、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,運行成功!