设计一个单片机键盘接口电路,实现4*4矩阵键盘,用数码管显示相应按键内容,当指定某一个按键连续被按三次时,显示“口”字符号,按键有去抖动功能,数码管可以通过清零键清零。
在设计4*4矩阵键盘基础上,完成两个数的加、减、乘、除运算,结果通过数码管或液晶显示。
//0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71 共阴
//0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E 共杨
#include
#define GPIO_DIG P0 //段选数码管
#define GPIO_KEY P2 //矩阵按键
sbit led = P1^0;
typedef unsigned char uchar;
typedef unsigned int uint;
uint keynum = 0;
uint count=0;
uchar code table[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
uchar code table0[]={0x5c};
void delay( uchar i ){
while( i-- );
}
void key44scan(void)//键盘扫描函数
{
// uint count=0;
uint t;
P2=0xfe;
t=P2;
t=t&0xf0;
if(t!=0xf0){
delay(100);
if(t!=0xf0)
{
t=P2;
count++;
switch(t)
{
case 0xee:keynum=1; break;
case 0xde:keynum=5; break;
case 0xbe:keynum=9; break;
case 0x7e:keynum=13; break;
}
P0=table[keynum];
while(t!=0xf0)
{
t=P2;
t=t&0xf0;
}
}
}
P2=0xfd;
t=P2;
t=t&0xf0;
if(t!=0xf0){
delay(100);
if(t!=0xf0)
{
t=P2;
count++;
switch(t)
{
case 0xed:keynum=2; break;
case 0xdd:keynum=6; break;
case 0xbd:keynum=10; break;
case 0x7d:keynum=14; break;
}
P0=table[keynum];
while(t!=0xf0)
{
t=P2;
t=t&0xf0;
}
}
}
P2=0xfb;
t=P2;
t=t&0xf0;
if(t!=0xf0){
delay(100);
if(t!=0xf0)
{
t=P2;
count++;
switch(t)
{
case 0xeb:keynum=3; break;
case 0xdb:keynum=7; break;
case 0xbb:keynum=11; break;
case 0x7b:keynum=15; break;
}
P0=table[keynum];
while(t!=0xf0)
{
t=P2;
t=t&0xf0;
}
}
}
P2=0xf7;
t=P2;
t=t&0xf0;
if(t!=0xf0){
delay(100);
if(t!=0xf0)
{
t=P2;
count++;
switch(t)
{
case 0xe7:keynum=4; break;
case 0xd7:keynum=8; break;
case 0xb7:keynum=12; break;
case 0x77:keynum=0; break;
}
P0=table[keynum];
while(t!=0xf0)
{
t=P2;
t=t&0xf0;
}
}
}
// if(count==3){
// count = 0;
// led =~ led;
// P0=table0[0];
// delay(1000);
// }
}
void main (){
led = 0;
while(1) {
key44scan();
if(count==3){
//count = 0;
led =~ led;
P0=table0[0];
// delay(1000);
}
if(count==4){
count = 0;
led =~ led;
P0=table[0];
// delay(1000);
}
}
}
#include"reg52.h"
#include"math.h"
#define uchar unsigned char
#define uint unsigned int
#define key P1
#define duan P2
#define wei P3
sbit led=P0^0;
sbit buzzer=P0^1;
uchar num,temp,num1,i=0;
long bczs=0,czs=0,jiguo=0,jiguo1=0;
uchar czs12=1; //输入数的选择标志位,1为第一个数,2为第二个数
uchar yiweiflag,qinflag; //移位标志
uchar code shuzi[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //0~9,-,
uchar code weizi[9]={0x00,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
uchar code error[10]={0xff,0xaf,0xc0,0xaf,0xaf,0x86,0xff,0xff,0xff};//error
uchar playshuzu[9],fuhao;
uchar temp1[8],mm[4],temp2[8];
uchar zhi,weishu=0;
void init(); //函数申明
uchar keyscan();
uchar scanzhi();
void display();
void duzhichuli();
void zhuandisplayjiguo();
void jiafa();
void jianfa();
void chengfa();
void chufa();
void qin();
void displayerror();
//======================================
void main() //主函数
{
init();
display();
while(1)
{
duzhichuli();
}
}
//===============================================================================
void init()
{
uchar i;
czs12=1;
yiweiflag=1; //1不移
qinflag=0; //不清除
duan=shuzi[8];
wei=weizi[5];
playshuzu[1]=shuzi[0];
for(i=2;i<9;i++)
playshuzu[i]=shuzi[10];
bczs=0;czs=0;jiguo=0,jiguo1=0;
}
//===============================================================================
void delay(uint x)
{
uchar y;
for(x;x>0;x--)
for(y=112;y>0;y--);
}
//====================================
uchar keyscan()
{
unsigned char recode,i,j;
for(i=0;i<4;i++)
{
P1=~(0x01<<i);
recode=P1>>4;
if(recode<0x0f)
{
for(j=0;j<4;j++)
{if(!(recode&0x01<<j))break;}
return (i<<2)+(j+1); //返回键值 1-16
}
delay(5); //延时5ms
}
return 0; //无按键返回
}
//========================================
uchar scanzhi()
{
uchar zhi,k;
k=keyscan();
switch(k)
{
case 0: zhi=27;break;
case 1: zhi=7;break;
case 2: zhi=8;break;
case 3: zhi=9;break;
case 4: zhi=24;break; // /
case 5: zhi=4;break;
case 6: zhi=5;break;
case 7: zhi=6;break;
case 8: zhi=23;break; //*
case 9: zhi=1;break;
case 10: zhi=2;break;
case 11: zhi=3;break;
case 12: zhi=22;break; //-
case 13: zhi=26;break; //nc
case 14: zhi=0;break;
case 15: zhi=25;break; //=
case 16: zhi=21;break; //+
}
return(zhi);
}
//===========================================
void duzhichuli()
{
uchar tt,u;
tt=scanzhi();
if(tt!=27)
{
led=0;
buzzer=0;
if(tt<=9)//数字输入
{
if(qinflag==1) qin();
qinflag=0;
if(yiweiflag!=1)
{
for(u=8;u>1;u--) //移位输入
{
playshuzu[u]=playshuzu[u-1];
}
}
yiweiflag=0; //移位
playshuzu[1]=shuzi[tt];
if(czs12==1) bczs=bczs*10+tt; //
if(czs12==2) czs=czs*10+tt;
}
if(tt>20)//符号输入
{
switch(tt)
{
case 21: jiafa();break; //+
case 22: jianfa();break; //-
case 23: chengfa();break; //*
case 24: chufa();break;
case 25: zhuandisplayjiguo();break; //=
case 26: init();break; //nc
}
}
}
//-----------------------------------------------
while(tt!=27) //松手检测
{
led=0;
buzzer=0;
tt=scanzhi();
delay(1);
if(tt==27) goto chu;
}
chu: delay(1);
led=1;
buzzer=1;
}
//============================================
void display()
{
TMOD=0x01;
TH0=(65536-200)/256;
TL0=(65536-200)%256;
EA=1;
ET0=1;
TR0=1;
}
void TIME0(void) interrupt 1
{
TH0=(65536-200)/256;
TL0=(65536-200)%256;
i++;
if(i==9) i=1;
wei=weizi[i];
duan=playshuzu[i];
}
//=============================================== //显示数转操作数
void zhuandisplayjiguo()
{
uchar i,k;
long ttt;
for(i=1;i<9;i++)
playshuzu[i]=shuzi[10];
//----------------------------------------
switch(fuhao)
{
case 1: jiguo=bczs+czs;break;
case 2: jiguo=bczs-czs;break;
case 3: jiguo=bczs*czs;break;
case 4: jiguo=bczs/czs;break;
case 0: jiguo=jiguo1;break;
}
fuhao=0;
//----------------------------------------
ttt=jiguo;
jiguo1=jiguo; //显示处理
k=1; //取数的个数
for(i=1;i<=8;i++)
{
if(ttt/10!=0) k++;
ttt=ttt/10;
}
for(i=8;i>k;i--)
{
playshuzu[i]=shuzi[10];
}
if(jiguo<0) { jiguo=fabs(jiguo);playshuzu[k+1]=shuzi[11]; } //取正加负号
for(i=1;i<=k;i++)
{
playshuzu[i]=shuzi[jiguo%10];
jiguo=jiguo/10;
}
if(jiguo1>99999999) displayerror();
}
//===================================================
void qin()
{
uchar i;
yiweiflag=1; //1不移
playshuzu[1]=shuzi[0];
for(i=2;i<9;i++)
playshuzu[i]=shuzi[10];
}
//===================================================
void displayerror()
{
uchar i;
for(i=1;i<=8;i++)
playshuzu[i]=error[i];
}
//===================================================
void jiafa() //+
{
qinflag=1;
if(jiguo1!=0) bczs=jiguo1;
czs=0;
czs12=2;
fuhao=1; //+
}
void jianfa()
{
qinflag=1;
if(jiguo1!=0) bczs=jiguo1;
czs=0;
czs12=2;
fuhao=2; //-
}
void chengfa()
{
qinflag=1;
if(jiguo1!=0) bczs=jiguo1;
czs=0;
czs12=2;
fuhao=3; //*
}
void chufa()
{
qinflag=1;
if(jiguo1!=0) bczs=jiguo1;
czs=0;
czs12=2;
fuhao=4; // /
}
大佬们,可以支持一下。谢谢!!!
实验一 矩阵键盘中断实验 数码管显示
实验二 矩阵键盘简易计算器 LCD显示