51单片机100例实例之17例
//项目名称:数码管显示矩阵键盘按键值
//项目再创作者:科技小宅神
//完成时间:2021/01/21

#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
//定义蜂鸣器接口位置
sbit BEEP = P3^0;
//七段数码管数组:1~16-0
uchar code DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00};
//上次按键号和当前按键序号,在矩阵键盘中,序号范围为0~15,16则为无按键
uchar Pre_KeyNO = 16,KeyNO = 16;
//延时子程序
void DelayMS(uint ms)
{
uchar t;
while(ms--)
{
for(t=0;t<120;t++);
}
}
//矩阵键盘扫描子程序
void Keys_Scan()
{
uchar Tmp;
P1 = 0x0f;//高4位置0,放入4行
DelayMS(1);
Tmp = P1 ^ 0x0f;//按键按下后0x0f变成0000 xxxx,
//x中有1个为0,其他任为1,通过异或把3个1变成0,唯一的0变成1
switch(Tmp)//判断按键发生于0~3那一列
{
case 1: KeyNO = 0; break;//第一列
case 2: KeyNO = 1; break;//第二列
case 4: KeyNO = 2; break;//第三列
case 8: KeyNO = 3; break;//第四列
default: KeyNO = 16;//无按键按下
}
P1 = 0xf0;//低4位置0,放入4列
DelayMS(1);
Tmp = P1 >> 4 ^ 0x0f;//按键按下后0x0f变成 xxxx 0000,
//x中有1个为0,其他任为1,通过右移,高4位转移到低4位,
//并异或把3个1变成0,唯一的0变成1
switch(Tmp)//对0~3行分别附加起始值0,4,8,12
{
case 1: KeyNO += 0; break;
case 2: KeyNO += 4; break;
case 4: KeyNO += 8; break;
case 8: KeyNO += 12;
}
}
//蜂鸣器
void Beep()
{
uchar i;
for(i=0;i<100;i++)
{
DelayMS(1);
BEEP = ~BEEP;//取反
}
BEEP = 0;//给低电平,恢复不响工作状态
}
//主程序
void main()
{
P0 = 0x00;//初始化
while(1)//死循环
{
P1 = 0xf0;//初始化
if(P1 != 0xf0)//当有按下按键,则进行矩阵键盘扫描子程序(获得按键序号)
Keys_Scan();
if(Pre_KeyNO != KeyNO)//上次按键号和当前按键序号不一致时,
{
P0 = ~DSY_CODE[KeyNO];//通过按键值,在数组中取得相应的值,并从P0口输出
Beep();
Pre_KeyNO = KeyNO;//上次按键序号=当前按键序号
}
DelayMS(100);
}
}