由于前几天出差,博客没有更新,今天看了看Tiny4412的原理图,把按键扫描程序写了一下,用的是轮询方式,后面会有中断方式的实现,闲话少说,进入正题,程序由前一个实验Tiny4412之C语言实现流水灯更改而来:
一、控制原理说明
先看一下原理图:
首先把按键对应的GPIO设置为输入模式,修改GPX3CON寄存器(板子不同,可能对应的GPIO管脚不同),通过上图可知当没有按下按键时,对应的GPIO状态为高电平,当有按键被按下时,对应的GPIO变为低,我们在程序一直检测这几个GPIO状态即可;
二、程序说明
其中Start.s文件同上一个实验完全相同;链接脚本key.lds的内容和led.lds完全相同,只把名字改了改;Makefile的内容也大部分一样,也只是改了改里边文件的名字,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
|
/*
* 程序说明
* 一上电,4个LED全亮,当某个按键被按下,则对应的LED熄灭(可同时按下多个键)
* 对应关系:KEY1-LED1,KEY2-LED2,KEY3-LED3,KEY4-LED4
*/
//按键对应的GPIO
#define GPX3CON (*(volatile unsigned int *)0x11000C60)
#define GPX3DAT (*(volatile unsigned int *)0x11000C64)
//LED对应的GPIO
#define GPM4CON (*(volatile unsigned int *)0x110002E0)
#define GPM4DAT (*(volatile unsigned int *)0x110002E4)
void
delay(
volatile
int
time
)
{
for
(;
time
> 0;
time
-- )
;
}
int
main(
void
)
{
unsigned
long
tmp = 0;
unsigned
char
keyValue = 0;
/*
* GPX3_2-GPX3_5 设置为输入功能,用于检测按键引脚的状态
*/
tmp = GPX3CON;
tmp &= ~(0xffff << 8);
GPX3CON = tmp;
/*
* GPM4_0-GPM4_3 设置为输出功能,用于控制LED的亮灭
*/
tmp = GPM4CON;
tmp &= ~0xffff;
tmp |= 0x1111;
GPM4CON = tmp;
while
(1)
{
//读按键引脚状态
keyValue = GPX3DAT;
keyValue = (keyValue & (0xf << 2)) >> 2;
if
(keyValue != 0xf)
//说明有按键被按下,再详细判断是哪个按键被按下
{
delay(1000);
//防抖
keyValue = GPX3DAT;
keyValue = (keyValue & (0xf << 2)) >> 2;
GPM4DAT = ~keyValue;
//设置LED亮、灭
}
else
{
GPM4DAT = 0x00;
}
}
return
0;
}
|
其中注释也比较详细,控制原理上边也说得很清楚了,这里就不多说了,有问题可以留言。
三、程序编译及烧写
1.编译
通过FTP或者其他工具将Start.s、Makefile、key.lds 、key.c四个文件上传到服务器上去,输入make命令进行编译将得到key.bin文件。
2.烧写
将SD卡插入电脑,并让VmWare里的Ubuntu识别出来,然后执行如下命令:
1
|
sudo ./sd_fusing.sh /dev/sdb ../3_key_scan/key.bin
|
如下图所示:
四、上电实验
上图所示,图一是没有按键被按下,四个LED全都被点亮,图二是有两个键被我同时按下