更多单片机学习笔记:
单片机学习笔记 1. 点亮一个LED灯
单片机学习笔记 2. LED灯闪烁
单片机学习笔记 3. LED灯流水灯
单片机学习笔记 4. 蜂鸣器滴~滴~滴~
单片机学习笔记 5. 数码管静态显示
单片机学习笔记 6. 数码管动态显示
单片机学习笔记 7. 独立键盘
目录
0、实现的功能
4*4矩阵键盘+独立键盘的按键检测,可拓展为四管显示
1、Keil工程
1-1 矩阵键盘识别方法
主要采用列扫描(1111 0000)和行扫描(0000 1111)的方法。
列扫描的初始操作是输入P3口为0xF0,当S6被按下时,P34由1会变为0,此时P3口为0xE0;同理,S10被按下时,P3也为0xE0。所以第一列被按下时,P3为1110 0000;第二列被按下时,P3为1101 0000;第三列被按下时,P3为1011 0000;第四列被按下时,P3为0111 0000。
所以P30--P33为行线,P34--P37为列线
再做行扫描,P3初始为0x0F。当S6被按下时,P30会从1变为0,P3为0000 1110.最后再和列扫描的结果相加:1110 0000 + 0000 1110 = 1110 1110,得到确切的位置(第一列,第一行)
所以P3的数据中,前四位为哪一列,后四位为哪一行。谁为0就是哪一行列
1-2 swich语句
主要涉及到c语言中的switch语句
2、代码实现
显示的按键序号和对应显示数字表如下:
只要是涉及到按键的,都要进行软件消抖+松手检测。赋值P3=0xf0进行列扫描,找到是哪一列,KeyValue可以直接为0 1 2 3------赋值P3=0x0f进行行扫描,每行之间相差4,此时KeyValue对应的+4即可
独立按键扫描的话,赋值P3=0xff,这样就不是列扫描和行扫描了。按下哪个,哪一位就为0,找到对应的显示数字即可
代码实现:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit WE = P2^7; //锁存器位选,U8的LE,选择哪个数码管
sbit DU = P2^6; //锁存器段选,U9的LE,控制亮什么数字
uchar KeyValue = 6; //按键显示值
//共阴极数码管段选表0-9
uchar code table1[] = {
//0 1 2 3 4 5 6 7 8
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f,
//9 A B C D E F H L
0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x76, 0x38,
//n u - 熄灭
0x37, 0x3e, 0x40, 0x00} ;
//延时模块
void delay(uint z)
{
uint x;
uint y;
for(x = z; x > 0; x--)
for(y = 114; y > 0; y--);
}
void KeyScan()
{
//4*4矩阵键盘扫描
P3 = 0xf0; //列扫描初始化
if(P3 != 0xf0) //判断按键是否被按下
{
delay(10); //软件消抖10ms
if(P3 != 0xf0) //再判断是否真正被按下,有可能是误触
{
switch(P3) //判断哪一列被按下
{
case 0xe0: KeyValue = 0; break; //第一列
case 0xd0: KeyValue = 1; break; //第二列
case 0xb0: KeyValue = 2; break; //第三列
case 0x70: KeyValue = 3; break; //第四列
}
P3 = 0x0f; //行扫描初始化
switch(P3) //判断哪一行被按下
{
case 0x0e: KeyValue = KeyValue; break; //第一行
case 0x0d: KeyValue = KeyValue + 4; break; //第二行
case 0x0b: KeyValue = KeyValue + 8; break; //第三行
case 0x07: KeyValue = KeyValue + 12; break; //第四行
}
while(P3 != 0x0f); //松手检测
}
}
//独立按键扫描
P3 = 0xff;
if(P3 != 0xff)
{
delay(10); //软件消抖10ms
if(P3 != 0xff)
{
switch(P3) //判断哪一行被按下
{
case 0xfe: KeyValue = 16; break; //S2
case 0xfd: KeyValue = 17; break; //S3
case 0xfb: KeyValue = 18; break; //S4
case 0xf7: KeyValue = 19; break; //S5
}
while(P3 != 0xff); //松手检测
}
}
}
void main()
{
//指定第一个数码管,不用放在循环里
P0 = 0xff;//清除断码,让位锁存器哪个都不选
WE = 1;//位选锁存打开
P0 = 0xfe;//选第一个管
WE = 0; //进入锁存
while(1)
{
KeyScan(); //20个按键扫描
DU = 1;//段选锁存打开
P0 = table1[KeyValue];
DU = 0;//进入锁存
}
}
可以结合数码管动态显示,弄点好玩的
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit WE = P2^7; //锁存器位选,U8的LE,选择哪个数码管
sbit DU = P2^6; //锁存器段选,U9的LE,控制亮什么数字
uchar KeyValue = 6; //按键显示值
//共阴极数码管段选表0-9
uchar code table1[] = {
//0 1 2 3 4 5 6 7 8
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f,
//9 A B C D E F H K
0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x76, 0x76,
//n u - 熄灭
0x37, 0x3e, 0x40, 0x00} ;
//延时模块
void delay(uint z)
{
uint x;
uint y;
for(x = z; x > 0; x--)
for(y = 114; y > 0; y--);
}
void KeyScan()
{
//4*4矩阵键盘扫描
P3 = 0xf0; //列扫描初始化
if(P3 != 0xf0) //判断按键是否被按下
{
delay(10); //软件消抖10ms
if(P3 != 0xf0) //再判断是否真正被按下,有可能是误触
{
switch(P3) //判断哪一列被按下
{
case 0xe0: KeyValue = 0; break; //第一列
case 0xd0: KeyValue = 1; break; //第二列
case 0xb0: KeyValue = 2; break; //第三列
case 0x70: KeyValue = 3; break; //第四列
}
P3 = 0x0f; //行扫描初始化
switch(P3) //判断哪一行被按下
{
case 0x0e: KeyValue = KeyValue; break; //第一行
case 0x0d: KeyValue = KeyValue + 4; break; //第二行
case 0x0b: KeyValue = KeyValue + 8; break; //第三行
case 0x07: KeyValue = KeyValue + 12; break; //第四行
}
while(P3 != 0x0f); //松手检测
}
}
//独立按键扫描
P3 = 0xff;
if(P3 != 0xff)
{
delay(10); //软件消抖10ms
if(P3 != 0xff)
{
switch(P3) //判断哪一行被按下
{
case 0xfe: KeyValue = 16; break; //S2
case 0xfd: KeyValue = 17; break; //S3
case 0xfb: KeyValue = 18; break; //S4
case 0xf7: KeyValue = 19; break; //S5
}
while(P3 != 0xff); //松手检测
}
}
}
void main()
{
while(1)
{
KeyScan(); //20个按键扫描
P0 = 0xff;//清除断码,让位锁存器哪个都不选
WE = 1;//位选锁存打开
P0 = 0xfe;//选第一个管
WE = 0; //进入锁存
DU = 1;//段选锁存打开
P0 = table1[KeyValue];
DU = 0;//进入锁存
delay(5);
P0 = 0xff;//清除断码,让位锁存器哪个都不选
WE = 1;//位选锁存打开
P0 = 0xfd;//选第2个管
WE = 0; //进入锁存
DU = 1;//段选锁存打开
P0 = table1[KeyValue+4];
DU = 0;//进入锁存
delay(5);
P0 = 0xff;//清除断码,让位锁存器哪个都不选
WE = 1;//位选锁存打开
P0 = 0xfb;//选第3个管
WE = 0; //进入锁存
DU = 1;//段选锁存打开
P0 = table1[KeyValue-3];
DU = 0;//进入锁存
delay(5);
P0 = 0xff;//清除断码,让位锁存器哪个都不选
WE = 1;//位选锁存打开
P0 = 0xf7;//选第4个管
WE = 0; //进入锁存
DU = 1;//段选锁存打开
P0 = table1[KeyValue+2];
DU = 0;//进入锁存
delay(5);
}
}
实物展示:
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » 单片机学习笔记 8. 矩阵键盘按键检测
发表评论 取消回复