/*
*******************************************************************************
目标
做一个简易的加法计算器
功能分析
按下键盘数字,显示到数码管
按下加号 数码管清零,记录下一个数字
直到按下回车键 显示出结果
构思
按键扫描函数,检测4次报告哪个键被有效按下 keyscan
按键驱动函数,再主程序里面不断进行循环检测按键 keydrive
按键动作函数,根据按下的不同键,输出给不同的数值 keyaction
数码管显示函数,根据不同的按键值显示数码管数值 ledshow
数码管扫描函数,每1ms切换点亮数码管 ledscan
*******************************************************************************
*/
#include <reg52.h>
//数码管相关
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
//按键相关
sbit key1=P2^4;
sbit key2=P2^5;
sbit key3=P2^6;
sbit key4=P2^7;
unsigned char key[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
unsigned char code keycodemap[4][4]={{1,2,3,10},{4,5,6,11},{7,8,9,12},{0,14,15,16}}; //按键数值设定
unsigned char code ledchar[]={0XC0,0XF9,0XA4,0XB0,
0X99,0X92,0X82,0XF8,0X80,0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E};//数码管数值取值
unsigned char leddd[6]={0xff,0xff,0xff,0xff,0xff,0xff};
void ledshow(unsigned long number)//对按键传递的数值进行显示
{
unsigned char k;
unsigned char cnt=0;
unsigned char shu;
for(k=0;k<6;k++)
leddd[k]=0xff;
if(number==0)leddd[0]=ledchar[0];
while(number!=0)
{
shu=number%10;
number=number/10;
leddd[cnt]=ledchar[shu];
cnt++;
}
}
void keyaction(unsigned char k,unsigned char l)
{
static unsigned long number=0;
static unsigned long sum=0;
if(keycodemap[k][l]>=0&&keycodemap[k][l]<=9)//输入的是数字
{
number=number*10+keycodemap[k][l];
if(number>999999)number=0;
ledshow(number);
}
else if(keycodemap[k][l]==10)//输入的是向上键
{
ledshow(0);
sum=sum+number;
number=0;
}
else if(keycodemap[k][l]==15)//输入的是回车
{
sum=sum+number;
if(sum>999999)sum=0;
ledshow(sum);
sum=0;
number=0;
}
else
{
sum=0;
number=0;
ledshow(0);
}
}
void keydrive()
{
unsigned char i,j;
static unsigned char old[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
if(key[i][j]!=old[i][j])//按键被按下
{
if(old[i][j]==1)
keyaction(i,j); //对不同按键数值进行反应
old[i][j]=key[i][j];
}
}
}
void keyscan() //每1ms对按键值进行扫描
{
unsigned char z=0;
static unsigned char keyout=0;
static unsigned char keyy[4][4]={{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff},
{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
//对这一排的按键进行扫描
keyy[keyout][0]=(keyy[keyout][0]<<1)|key1;
keyy[keyout][1]=(keyy[keyout][1]<<1)|key2;
keyy[keyout][2]=(keyy[keyout][2]<<1)|key3;
keyy[keyout][3]=(keyy[keyout][3]<<1)|key4;
//判断四次扫描数值
for(z=0;z<4;z++)
{
if((keyy[keyout][z]&0x0f)==0x0f)
key[keyout][z]=1;
else if ((keyy[keyout][z]&0x0f)==0x00)
key[keyout][z]=0;
}
//切换不同排数
keyout++;
if (keyout>=4)keyout=0;
switch (keyout)
{
case 0:P2=0XF7;break;
case 1:P2=0XFB;break;
case 2:P2=0XFD;break;
case 3:P2=0XFE;break;
default:break;
}
}
void ledscan() //按键扫描
{
static unsigned char sis=0;
P0=0xff;//消隐
switch(sis)
{
case 0:ADDR2=0;ADDR1=0;ADDR0=0;sis++;P0=leddd[0];break;
case 1:ADDR2=0;ADDR1=0;ADDR0=1;sis++;P0=leddd[1];break;
case 2:ADDR2=0;ADDR1=1;ADDR0=0;sis++;P0=leddd[2];break;
case 3:ADDR2=0;ADDR1=1;ADDR0=1;sis++;P0=leddd[3];break;
case 4:ADDR2=1;ADDR1=0;ADDR0=0;sis++;P0=leddd[4];break;
case 5:ADDR2=1;ADDR1=0;ADDR0=1;sis=0;P0=leddd[5];break;
default :break;
}
}
void main()
{
//打开138
ENLED=0;
ADDR3=1;
//打开定时
TMOD=0X01;
TH0=0XFC;
TL0=0X67;
EA=1;
ET0=1;
TR0=1;
leddd[0]=ledchar[0];
while(1)
{
keydrive();
}
}
void interruptTimer0() interrupt 1
{
TH0=0XFC;
TL0=0X67;
ledscan();
keyscan();
}
51 简易加法计算器
最新推荐文章于 2022-09-15 10:52:06 发布
2045

被折叠的 条评论
为什么被折叠?



