#include<reg51.h>
#include<stdio.h>
#include<stdlib.h>
#include<intrins.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define wc 0x8fff
#define wd 0xdfff
#define rc 0xbfff
void displayListChar(unsigned char X, unsigned char Y, uchar DData);
uchar dispbuf[]={'0','1','2','3','4','5','6','7','8','9',':'};
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e,0x00
};
uchar second;
uchar temp1;
uchar minute;
uchar hour;
uint tcnt,g;
uchar suanfa;
bit flag2;
bit flag1=1;//////控制计算器还是液晶调整的状态灯
uint i=0,f,m,g,s,t;// for里的计数值,用于循环
// 用来标记按了什么,如+,-.*,或是/
sbit P2_0=P2^0;// 定义P2.0口用来,当计算值超过15时,P2.0所对应的灯闪几下
sbit P2_1=P2^1;// 定义P2.1口用来,当除数为0时,P2.1所对应的灯闪几下
sbit P2_2=P2^2;
sbit P2_3=P2^3;
uint num[4]={0}; //用于记录外面输入的数字
uint Tablenum;
sbit P3_4=P3^4;
sbit P3_5=P3^5;
void jieguo(void);
void Settime(uchar verify);
uchar kbscan(void);///键盘扫描
void Show_Time(void);////显示时间
void Settime(uchar verify);//verify 在这里为调整的意思
uint transfor( uchar key1);
void delay400ms(void) ;
void delay200ms(void);
void delay5ms(void);
void delay_1s(void);
void dlms(void);
void dlms1(void)
{
uint g=20000;
while(--g); //延时100mS钟
}
void clr(void)
{
i=0;
suanfa=0;
Tablenum=0;
for(f=0;f<4;f++)
{
num[f]=0;
}
P2_0=1;
P2_1=1;
P2_2=1;
P2_3=0;
P3_4=0;
P3_5=1;
P0=0xc0;
P3_5=0;
}
//***************************************************************************************************
//***************************************以下液晶驱动****************************************************
void waitLcd() //just wait until 液晶不忙为止
{
char temp;
bit flag=1;
while(flag==1)
{
temp=XBYTE[rc];
if (temp>>7==0) flag=0;
P1=temp;
}
P1=0xff;
}
//just wait until 液晶不忙为止
void WriteCommand_Lcd(bit isCheck,char c)
{
if (isCheck==1) waitLcd();
XBYTE[wc]=c;
}
void writedata(char c)
{
waitLcd();
XBYTE[wd]=c;
}
void LcdInit()
{
delay5ms();
delay5ms();
delay5ms();
WriteCommand_Lcd(0,0x38); //三次显示模式设置,不检测忙信号
delay5ms();
WriteCommand_Lcd(0,0x38);
delay5ms();
WriteCommand_Lcd(0,0x38);
delay5ms();
WriteCommand_Lcd(1,0x38); //显示模式设置,开始要求每次检测忙信号,8位2行5*7
WriteCommand_Lcd(1,0x08); //关闭显示
WriteCommand_Lcd(1,0x01); //清显示
WriteCommand_Lcd(1,0x06); // 文字不动,光标右移
WriteCommand_Lcd(1,0x0C); // 显示开及光标设置
}
void displayListChar(unsigned char X, unsigned char Y, uchar DData)
{
Y &= 0x1;
X &= 0xF;
if (X <= 0xF)
{
Y &= 0x1;
X &= 0xF;
if (Y) X |= 0x40;
X |= 0x80;
WriteCommand_Lcd(0,X);
writedata(dispbuf[DData]);
}
}
//****************************************以上液晶驱动*****************************************************
//*****************************************************************************************************
//**********************************以下显示时间*****************************************************
void Show_Time(void)
{
displayListChar(0,0,hour/10);
displayListChar(1,0,hour%10);
displayListChar(2,0,10);
displayListChar(3,0,minute/10);
displayListChar(4,0,minute%10);
displayListChar(5,0,10);
displayListChar(6,0,second/10);
displayListChar(7,0,second%10);
}
//**********************************以上显示时间*****************************************************
void main(void)
{
TMOD=0x02; //置自动重装载模式
TH0=0x06; //设初值
TL0=0x06; //设初值
TR0=1; //开始计数
ET0=1; //开定时器/计数器
EA=1; //中断开
delay400ms();//启动等待,等LCM讲入工作状态
LcdInit(); //LCM初始化
P3_4=0;
P2_0=1;
P2_1=1;
P2_2=0;
P2_3=1;
P3_5=1;
P0=0xc0;
P3_5=0;
while(1)
{
uchar key;
key=kbscan();
dlms();
// 0(11100111 0xe7)
///*****************************以下是两种状态的切换********************
//**********************************************************************************************
if(key==0xe7)
{
dlms();
flag1=~flag1;
key=0x00;
if(flag1==1)
{
P2_0=1;
P2_1=1;
P2_2=0;///液晶状态灯
P2_3=1;
}
if(flag1==0)
{
P2_0=1;
P2_1=1;
P2_2=1;
P2_3=0;///计算器状态灯
}
dlms1();
}
///*****************************以上是两种状态的切换********************
//**********************************************************************************************
///**************************************************************************************
///*******************************用于调整时间********************************************
if(flag1==1)
{ LcdInit(); //LCM初始化
Show_Time();
if (key!=0)
{
if (key==0x7e)
{
dlms();
if (key==0x7e)
{
EA=0;
flag2=1;
}
key=0x00;
}
if (key==0x7d)
{
dlms();
if (key==0x7d)
{
EA=1;
flag2=0;
}
key=0x00;
}
Settime( key );
delay200ms();
}
}
//**************************************下面是计算器*************************
if(flag1==0)
{
WriteCommand_Lcd(1,0x01); //清显示
if ((key!=0x7e)&&(key!=0x7d)&&(key!=0x7b)&&(key!=0x77)&&(key!=0xd7)&&(key!=0xb7)&&(key!=0x00))
{//0x7e为"+",0x7d为"-",0x7b为"*",0x77为"/".0xd7为"CLR",0xb7为"="
Tablenum=transfor(key);
if (Tablenum!=0)
{
num[i]=Tablenum;
P3_5=1;
P0=(table[Tablenum]);//这里的key只能进来0至9
P3_5=0;
}
}
if ((key==0x77)||(key==0x7d)||(key==0x7b)||(key==0x7e))
{
i++;
if (i>1) {i=1;}
if (key==0x7e) { suanfa=1;}
if (key==0x7d) { suanfa=2;}
if (key==0x7b) { suanfa=3;}
if (key==0x77) { suanfa=4;}
}
if (key==0xb7) // 按等号(0xb7) 给P2赋值
{
jieguo();
}
// 按等号 给P2赋值
if (key==0xd7) //如果按清零,则清零
{
clr();
}
//如果按清零,则清零
}
//**************************************上面是计算器************************************************
//**********************************************************************************************
}//此括号为while 的括号
}
void delay5ms(void)
{
unsigned int TempCya = 277;
while(--TempCya);
}
//延时400ms
void delay400ms(void)
{
unsigned int TempCya = 22160;
while(--TempCya);
}
//延时400ms
void delay200ms(void)
{
unsigned int TempCyaaa = 11080;
while(--TempCyaaa);
}
//*****************************定时器********************************************
//*****************************定时器********************************************
void timer0(void) interrupt 1 using 1
{
tcnt++;
if(tcnt==2000)
{
tcnt=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
}
//*****************************显示结果*********************************************
//*****************************显示结果*********************************************
void jieguo(void)
{
i=0;
if (suanfa==1)
{
num[2]=(num[1]+num[0]);
if((num[2]<=15)&&(num[2]>=0))
{
P3_5=1;
P0=table[num[2]];
P3_5=0;
}
else
{ clr();
for(m=0;m<8;m++)
{
P2_0=~P2_0;
delay_1s();
}
}
}
if (suanfa==2)//减法显示
{
num[2]=(num[0]-num[1]);
if((num[2]<=15)&&(num[2]>=0))
{
P3_5=1;
P0=table[num[2]];
P3_5=0;
}
else
{ clr();
for(m=0;m<8;m++)
{
P2_0=~P2_0;
delay_1s();
}
}
}//减法显示
if (suanfa==3)//乘法显示
{
num[2]=(num[0]*num[1]);
if((num[2]<=15)&&(num[2]>=0))
{
P3_5=1;
P0=table[num[2]];
P3_5=0;
}
else
{ clr();
for(m=0;m<8;m++)
{
P2_0=~P2_0;
delay_1s();
}
}
}//乘法显示
if (suanfa==4)//除法显示
{
if (num[1]!=0)
{
num[2]=(num[0]/num[1]);
if((num[2]<=15)&&(num[2]>=0))
{
P3_5=1;
P0=table[num[2]];
P3_5=0;
}
else
{ clr();
for(m=0;m<8;m++)
{
P2_0=~P2_0;
delay_1s();
}
}
}
else
{
for(m=0;m<8;m++)
{
P2_1=~P2_1;
delay_1s();
}
clr();
}
}//除法显示
suanfa=0;
}
//*****************************显示结果*********************************************
uint transfor( uchar key1)
{
uint temp;
switch (key1)
{
case 0xee: temp=1;break;
case 0xde: temp=2;break;
case 0xbe: temp=3;break;
case 0xed: temp=4;break;
case 0xdd: temp=5;break;
case 0xbd: temp=6;break;
case 0xeb: temp=7;break;
case 0xdb: temp=8;break;
case 0xbb: temp=9;break;
default: temp=0;break;
}
return temp;
}
//*******************************以下时间调节******************************************************
//*******************************以下时间调节******************************************************
void Settime(uchar verify)
{
//键盘设置
// 1 /hour+ (0xee) 2/minute+ 0xde 3/second+ 0xbe +
// 4/hour- 0xed 5/ minute- 0xdd 6/second- 0xbd -
// 7 8 9 *
// 0 CLR = /
////hour+的代码
if(flag2)
{
if (verify==0xee)
{
dlms();
if (verify==0xee)
{
hour++;
if(hour==24)
{
hour=0;
}
//while(verify==0xee);
verify=0x00;
}
// 1 /hour+ (0xee) 2/minute+ 0xde 3/second+ 0xbe
}
///minute +的代码
else if (verify==0xde)
{
dlms();
if (verify==0xde)
{
minute++;
if(minute==60)
{
minute=0;
}
//while(verify==0xde);
verify=0x00;
}
// 1 /hour+ (0xee) 2/minute+ 0xde 3/second+ 0xbe
}
//////second++的代码
else if (verify==0xbe)
{
dlms();
if (verify==0xbe)
{
second++;
if(second==60)
{
second=0;
}
// while(verify==0xbe);
verify=0x00;
}
// 1 /hour+ (0xee) 2/minute+ 0xde 3/second+ 0xbe
}
//////hour- (0xed) 的代码
else if (verify==0xed)
{
dlms();
if (verify==0xed)
{
if(hour==0)
{hour=24;
}
hour--;
// if(hour==0)
// {
// hour=23;
//}
//while(verify==0xed);
verify=0x00;
}
}
// 4/hour- 0xed 5/ minute- 0xdd 6/second- 0xbd
///下面为minute -的代码
else if (verify==0xdd)
{
dlms();
if (verify==0xdd)
{ if(minute==0)
{minute=60;}
minute--;
//if(minute==0)
//{
// minute=59;
//}
//while(verify==0xdd);
verify=0x00;
}
}
// 4/hour- 0xed 5/ minute- 0xdd 6/second- 0xbd
///下面为second -的代码
else if (verify==0xbd)
{
dlms();
if (verify==0xbd)
{ if(second==0)
{second=60;}
second--;
//if(second==0)
//{
// second=59;
//}
// while(verify==0xbd);
verify=0x00;
}
// 4/hour- 0xed 5/ minute- 0xdd 6/second- 0xbd
}
}
}
//*******************************以上时间调节******************************************************
//*******************************以上时间调节******************************************************
//******************************键盘扫描**********************************************
//******************************键盘扫描**********************************************
uchar kbscan(void)
{
uchar sccode;
P1=0xf0;
if( (P1&0xf0)!=0xf0 )
{
dlms();
if((P1&0xf0)!=0xf0)
{
sccode=0xfe;
while ((sccode&0x10)!=0)
{
P1=sccode;
if ((P1&0xf0)!=0xf0)
{
temp1=P1;
return temp1;
}
else
{
sccode=(sccode<<1)|0x01;
}
}
}
}
return (0);
}
//******************************键盘扫描**********************************************
//******************************键盘扫描**********************************************
void dlms(void)
{
g=554;
while(g--); //延时10mS钟
}
void delay_1s(void)
{
s=27750;
while(s--);//延时1S钟
}