【ARM】2410裸机系列-按键查询式控制led
开发环境
-
硬件平台: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设置为输入,用于读取;
-
将KSCAN0,KSCAN1,KSACAN2,设置为输出,并分别设置为0,1,1或1,0,1或1,1,0三种情况,这样可用于区分K1、K2、K3中哪个键按下去。
例如先让KSCAN0~2 = 011,那么K1被按下时,EINT19才会变为低电平,这时K2按下时,EINT19不会变低,这样就区分了按键K1和K2,区分其它按键原理一样。
寄存器配置
有关LED的寄存器的配置:(设置GPF4-GPF7为输出)
按键方面涉及到寄存器配置(设置相关寄存器输入输出)
精简原理图
程序源代码
//led_key.c
1 #include "2410addr.h" 2 3 void delay(long long max) //延迟函数 4 { 5 for(; max > 0; max--); 6 7 } 8 9 int main(void) 10 { 11 int read_value; 12 13 rGPFCON = rGPFCON & (~(0xff) << 8) | (0x55 << 8); //设置4个LED灯为输出(GPF4-GPF7输出) 14 rGPFDAT |= (0xf << 4); //先将4个灯都熄灭掉 15 16 rGPGCON = (0 << 7) | (1 << 12) | (0 << 23); //GPG3, GPG11 输入,GPG6, GPE11, GPE13输出 17 rGPECON = (1 << 22) | (1 << 26); 18 19 while(1) 20 { 21 rGPEDAT &= (0 << 11); //将GPE11置0,同时将GPE13和GPG6置1 22 rGPEDAT |= (1 << 13); 23 rGPGDAT |= (1 << 6); 24 25 read_value = rGPGDAT & 0x808; //读取GPG11和GPG3的输入值 26 27 if((read_value & 0x800) == 0) //判断GPG11输入是否为0,以此判断K1键是否按下 28 { 29 read_value = 0x800; 30 delay(200000); //按键去抖 31 32 if((read_value &= rGPGDAT) == 0) 33 { 34 if((rGPFDAT & (1 << 4)) == 0) //判断D12是否亮着,如果亮着则熄灭,反之相反 35 rGPFDAT |= (0x1 << 4); 36 else 37 rGPFDAT &= (0xe << 4); 38 } 39 } 40 else 41 { 42 if((read_value & 0x8) == 0) //判断GPG3输入的值是否为0, 以此K4键是否按下 43 { 44 read_value = 0x8; 45 delay(200000); //按键去抖 46 47 if((read_value &= rGPGDAT) == 0) 48 { 49 if((rGPFDAT & (0x8 << 4)) == 0) //判断D9是都亮着,如果亮着则熄灭,反之相反 50 rGPFDAT |= (0x8 << 4); 51 else 52 rGPFDAT &= (0x7 << 4); 53 } 54 } 55 } 56 57 58 rGPEDAT |= (1 << 11); //将GPE11和GPE13置1,同时将GPG6置0 59 rGPEDAT |= (1 << 13); 60 rGPGDAT &= (0 << 6); 61 62 read_value = rGPGDAT & (0x8 << 8); //读取GPG11的值 63 64 if(read_value == 0) //判断GPG11是否输入0,以此判断K2键按下 65 { 66 read_value = 0x800; 67 delay(200000); //按键去抖 68 69 if((read_value &= rGPGDAT) == 0) 70 { 71 if((rGPFDAT & (0x2 << 4)) == 0) //判断D11是否亮着, 如果亮着则熄灭,反之相反 72 rGPFDAT |= (0x2 << 4); 73 else 74 rGPFDAT &= (0xd << 4); 75 } 76 } 77 78 rGPEDAT &= (0 << 13); //将GPE13置0, 同时将GPE11和GPG6置1 79 rGPEDAT |= (1 << 11); 80 rGPGDAT |= (1 << 6); 81 82 read_value = rGPGDAT & 0x800; //读取GPG11的值 83 84 if(read_value == 0) //判断GPG11是否为0,以此判断K3键是否按下 85 { 86 read_value = 0x800; 87 delay(200000); //按键去抖,延迟一段时间 88 89 if((read_value &= rGPGDAT) == 0) 90 { 91 if((rGPFDAT & (0x4 << 4)) == 0) //判断D10是否亮着,如果亮着则熄灭,反之相反 92 rGPFDAT |= (0x4 << 4); 93 else 94 rGPFDAT &= (0xb << 4); 95 } 96 } 97 } 98 99 return 0; 100 }
//启动文件start.S
1 .text 2 .global _start 3 _start: 4 #define WATCHDOG 0x53000000 5 ldr r0, =WATCHDOG 6 mov r1, #0 7 str r1, [r0] 8 9 ldr sp, =1024*4 10 bl main 11 12 loop: 13 b loop
//Makefile
1 led.bin:start.S led_key.c 2 arm-linux-gcc -c start.S -o start.o 3 arm-linux-gcc -c led_key.c -o led_key.o 4 arm-linux-ld -Ttext 0x30008000 start.o led_key.o -o led_key 5 arm-linux-objcopy -O binary -S led_key led_key.bin 6 clean: 7 rm -f *.o led_key.bin
编译
OK,生成 led_key.bin文件了
下载执行
OK,运行成功!