/***************************************************************
* 程序名称:精简的4*4矩阵键盘数码管显示程序
* 实验对象:XY850或XY-900型单片机开发板
* 硬件说明:MCU采用AT89S51/52或STC89C51/52,74HC573组合对数码管控制
* 编 写:月夜听风 更多资料请登陆:http://www.mcusy.cn
****************************************************************/
#include<reg52.h>
#define uchar unsigned char
sbit shu=P3^3; //选通段码-HC573
sbit wei=P3^4; //段码位码-HC573
const uchar code table[]= //数组、共阳数码管
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90, //数字0~9
0x88,0x83,0xc6,0xa1,0x86,0x8e}; //字母A~F
/*-------------------------延时函数--------------------------*/
void de1ms(uchar i)
{
uchar x,y;
for(x=0;x<i;x++)
{for(y=0;y<122;y++){;}} //延时1ms
}
/*---------------------矩阵扫描取值函数----------------------*/
uchar keyscan(void)
{
uchar scode,rcode;
P1=0xf0; //发全0行扫描码,列输入
if((P1&0xf0)!=0xf0) //若有键按
{ de1ms(10); //消抖
if((P1&0xf0)!=0xf0) //重测
{ scode=0xfe; //逐行扫描初值
while((scode&0x10)!=0)
{ P1=scode; //输出行扫描码
if((P1&0xf0)!=0xf0) //若本行有键按下
{ rcode=(P1&0xf0)|0x0f;
while((P1&0xf0)!=0xf0); //松手检测(视情况也可去掉这句)
return((~scode)+(~rcode)); //返回扫描键代码
}
else scode=(scode<<1)|0x01; //此行无键按下、行扫描码左移一位
}
}
}
return(0); //无键按下、则返回值为0
}
/*----------------------键值显示函数-------------------------*/
void display(uchar dis)
{
uchar num;
switch(dis) //键值比较/选择
{
case 0x41:num=0; break; // 0
case 0x88:num=1; break; // 1
case 0x48:num=2; break; // 2
case 0x28:num=3; break; // 3
case 0x84:num=4; break; // 4
case 0x44:num=5; break; // 5
case 0x24:num=6; break; // 6
case 0x82:num=7; break; // 7
case 0x42:num=8; break; // 8
case 0x22:num=9; break; // 9
case 0x18:num=10;break; // A
case 0x14:num=11;break; // B
case 0x12:num=12;break; // C
case 0x11:num=13;break; // D
case 0x81:num=14;break; // E
case 0x21:num=15;break; // F
default:break;
}
shu=1; P0=table[num]; shu=0; //开段选、送键值、关段选
wei=1; P0=0x40; wei=0;//开位选、第8个数码管、关位选
de1ms(5); //稍延时
}
/*-------------------------主函数----------------------------*/
void main(void)
{
uchar key;
while(1)
{
key=keyscan(); //键值赋予key
display(key); //调用显示
}
}
以下是4x4矩阵用LCD1602显示键值0~9:
/***************************************************************
* 程序名称:4*4矩阵键盘LCD1602显示0~9数
* 实验对象:XY850/XY900_USB型开发板
* 硬件说明:AT89S51/52或STC89C51/52,74HC573组合对数码管控制
* 编 写:月夜听风 更多资料请登陆:http://www.mcusy.cn
****************************************************************/
#include<reg52.h>
#include<LCD1602.h> //
#define uchar unsigned char
#define uint unsigned int
uchar code tab0[] = {" Key Enter : "};
uchar code tab1[] = {" = "}; //显示
sbit BELL=P3^7; //小喇叭
//--------------------------------------------------------------
void de1ms(uchar i) //延时1ms
{
uchar x,y;
for(x=0;x<i;x++)
{for(y=0;y<122;y++){;}}
}
//--------------------------------------------------------------
void BELL_alarm(uint m) //按键音、适合12M,参数m为时长
{
uchar y,j;
for(y=0;y<m;y++)
{BELL =~ BELL; for(j=0;j<25;j++);} //取反/频率
}
/*---------------------矩阵扫描取值函数----------------------*/
uchar keyscan(void)
{
uchar scode,rcode;
P1=0xf0; //发全0行扫描码,列输入
if((P1&0xf0)!=0xf0) //若有键按
{
de1ms(10); //消抖
if((P1&0xf0)!=0xf0) //重测
{
scode=0xfe; //逐行扫描初值
while((scode&0x10)!=0)
{
P1=scode; //输出行扫描码
if((P1&0xf0)!=0xf0) //若本行有键按下
{
rcode=(P1&0xf0)|0x0f;
while((P1&0xf0)!=0xf0); //松手检测(视情况也可去掉这句)
BELL_alarm(200);
return((~scode)+(~rcode)); //返回扫描键代码
}
else
scode=(scode<<1)|0x01; //此行无键按下、行扫描码左移一位
}
}
}
return(0); //无键按下、则返回值为0
}
/*----------------------键值显示函数-------------------------*/
void display(uchar dis)
{
uchar num;
switch(dis) //键值比较/选择
{
case 0x41: num=0; break; // 0
case 0x88: num=1; break; // 1
case 0x48: num=2; break; // 2
case 0x28: num=3; break; // 3
case 0x84: num=4; break; // 4
case 0x44: num=5; break; // 5
case 0x24: num=6; break; // 6
case 0x82: num=7; break; // 7
case 0x42: num=8; break; // 8
case 0x22: num=9; break; // 9
default:;break;
}
DisplayOne(5,1,num+0x30); //显示/第5位
}
/*-------------------------主函数----------------------------*/
void main(void)
{
char i; uchar key;
de1ms(100);
InitLcd(); //LCD初始化
for(i=15;i>=0;i--)
{
DisplayList(i,0,tab0);//第一行
DisplayList(i,1,tab1);//第二行
de1ms(500);
}
de1ms(100);
while(1)
{
key=keyscan(); //键值赋予key
display(key); //调用显示
}
}