开发环境
-
-
硬件平台: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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
#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
1
2
3
4
5
6
7
8
9
10
11
12
13
|
.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
1
2
3
4
5
6
7
|
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,运行成功!
本文转自infohacker 51CTO博客,原文链接:http://blog.51cto.com/liucw/1222050