delay1ms();
}
/*****************************************************
函数功能:
判断液晶模块的忙碌状态
返回值:
result。
result=1,忙碌;result=0,不忙
***************************************************/
unsignedcharBusyTest(void)
{
bitresult;
RS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1;//E=1,才允许读写
_nop_();//空操作
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
result=BF;//将忙碌标志电平赋给result
E=0;
returnresult;
}
/*****************************************************
函数功能:
将模式设置指令或显示地址写入液晶模块
入口参数:
dictate
***************************************************/
voidWriteInstruction(unsignedchardictate)
{
while(BusyTest()==1);//如果忙就等待
RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,
//就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_();//空操作两个机器周期,给硬件反应时间
P1=dictate;//将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:
指定字符显示的实际地址
入口参数:
x
***************************************************/
voidWriteAddress(unsignedcharx)
{
WriteInstruction(x|0x80);//显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:
将数据(字符的标准ASCII码)写入液晶模块
入口参数:
y(为字符常量)
***************************************************/
voidWriteData(unsignedchary)
{
while(BusyTest()==1);
RS=1;//RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,
//就是让E从0到1发生正跳变,所以应先置"0"
P1=y;//将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
delay_lcd(5);
}
/*****************************************************
函数功能:
对LCD的显示模式进行初始化设置
***************************************************/
voidLcdInitiate(void)
{
delay_lcd(15);//延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction(0x38);//显示模式设置:
16×2显示,5×7点阵,8位数据接口
delay_lcd(5);//延时5ms
WriteInstruction(0x38);
delay_lcd(5);
WriteInstruction(0x38);
delay_lcd(5);
WriteInstruction(0x0C);//显示模式设置:
显示开,无光标,不闪烁
delay_lcd(5);
WriteInstruction(0x06);//显示模式设置:
光标右移,字符不移
delay_lcd(5);
WriteInstruction(0x01);//清屏幕指令,将以前的显示内容清除
delay_lcd(5);
}
/*****************************************************
函数功能:
连续显示字符串
***************************************************/
voidLcdWriteString(unsignedcharaddress,unsignedchar*Date)
{
WriteAddress(address);
while(*Date!
='\0')
{
WriteData(*Date);//写数据
Date++;//地址++
delay_lcd(5);//适当延时
}
}
voidClearScreen()
{
LcdWriteString(0x00,"");
LcdWriteString(0x40,"");
}
voidDelay()
{
unsignedinti;
for(i=0;i<32000;i++);
}
voidWelcome()
{
unsignedintbeep_delay;
ucharj;
ClearScreen();
BEEP=0;
for(beep_delay=0;beep_delay<5000;beep_delay++);
BEEP=1;
LcdWriteString(0x10,"Welcome");
LcdWriteString(0x50,"Caculate");
for(j=0;j<16;j++)
{
WriteInstruction(0x18);
Delay();
}
LcdInitiate();
ClearScreen();
LcdWriteString(0x00,"0");
}
KEY:
#include"key.h"
voiddelay1()//延时子程序
{
unsignedcharn,m;
for(n=100;n>0;n--)
for(m=300;m>0;m--);
}
unsignedcharKeycan(void)//按键扫描程序P1.0--P1.3为行线P1.4--P1.7为列线
{
unsignedcharrcode,ccode;
P2=0xF0;//发全0行扫描码,列线输入
if((P2&0xF0)!
=0xF0)//若有键按下
{
delay1();//延时去抖动
if((P2&0xF0)!
=0xF0)
{rcode=0xFE;//逐行扫描初值
while((rcode&0x10)!
=0)
{
P2=rcode;//输出行扫描码
if((P2&0xF0)!
=0xF0)//本行有键按下
{
ccode=(P2&0xF0)|0x0F;
do{;}while((P2&0xF0)!
=0xF0);//等待键释放
return((~rcode)+(~ccode));//返回键编码
}
else
rcode=(rcode<<1)|0x01;//行扫描码左移一位
}
}
}
return0;//无键按下,返回值为0
}
voidKeyDispaly(unsignedcharpos,unsignedcharkey)
{
switch(key)
{
case0x18:
LcdWriteString(pos,"1");break;
case0x28:
LcdWriteString(pos,"2");break;
case0x48:
LcdWriteString(pos,"3");break;
case0x14:
LcdWriteString(pos,"4");break;
case0x24:
LcdWriteString(pos,"5");break;
case0x44:
LcdWriteString(pos,"6");break;
case0x12:
LcdWriteString(pos,"7");break;
case0x22:
LcdWriteString(pos,"8");break;
case0x42:
LcdWriteString(pos,"9");break;
case0x21:
LcdWriteString(pos,"0");break;
case0x11:
LcdWriteString(pos,".");break;
case0x41:
LcdWriteString(pos,"=");break;
case0x88:
LcdWriteString(pos,"+");break;
case0x84:
LcdWriteString(pos,"-");break;
case0x82:
LcdWriteString(pos,"*");break;
case0x81:
LcdWriteString(pos,"/");break;
default:
break;
}
}
unsignedcharKeyToNum(unsignedcharkey)
{
switch(key)
{
case0x18:
return1;break;
case0x28:
return2;break;
case0x48:
return3;break;
case0x14:
return4;break;
case0x24:
return5;break;
case0x44:
return6;break;
case0x12:
return7;break;
case0x22:
return8;break;
case0x42:
return9;break;
case0x21:
return0;break;
default:
return10;break;
}
}
计算部分:
#include"caculate.h"
ucharflag_plus;
ucharflag_minus;
ucharflag_multiply;
ucharflag_divide;
ucharflag_equal;
ucharflag_point;
ucharcount_point;
ucharflag_result;
uchartab_num;
ucharcount;
ucharflag_num2;
unsignedintbeep_delay;
sbitBEEP=P3^6;
unsignedcharcodedigit[]={"0123456789"};//定义字符数组显示数字
ucharge,shi,bai,qian,wan,shiwan,baiwan;
ucharp_shi,p_bai,p_qian,p_wan,p_shiwan,p_baiwan;
charpos=-1;
doubletemp_number1;
doubletemp_number2;
doublenumber1;
doublenumber2;
doubleresult,temp_result;
voidBeep(void);
voidPoint(void)
{
ClearScreen();
flag_result=0;
tab_num=0;
temp_number1=0;
temp_number2=0;
flag_plus=0;
flag_minus=0;
flag_multiply=0;
flag_divide=0;
flag_num2=0;
pos=-1;
LcdWriteString(0x00,"0");
}
voidInput_Number1(unsignedcharkey_press)
{
uchari;
floatpoint_num;
if(flag_result==1){ClearScreen();pos=-1;flag_result=0;}
pos++;
if(flag_point==0)
{
LcdWriteString(0x40,"");
if(temp_number1==0&&KeyToNum(key_press)==0){Point();}
KeyDispaly(pos,key_press);
temp_number1=temp_number1*10+KeyToNum(key_press);
if(temp_number1>999)
{
pos=-1;
ClearScreen();//清屏
LcdWriteString(0x40,"ERROR:
OVERFLOW");Beep();
temp_number1=0;
}
}
elseif(flag_point==1)
{
LcdWriteString(0x40,"");
count_point++;
KeyDispaly(pos,key_press);
point_num=KeyToNum(key_press);
for(i=0;ipoint_num=point_num*0.1;
temp_number1=temp_number1+key_press;
}
}
voidInput_Number2(unsignedcharkey_press)
{
uchari;
floatpoint_num;
if(flag_result==1){ClearScreen();pos=-1;flag_result=0;}
pos++;
flag_num2=1;
if(flag_point==0)
{
LcdWriteString(0x40,"");
if(temp_number1==0&&KeyToNum(key_press)==0){Point();}
KeyDispaly(pos,key_press);
temp_number2=temp_number2*10+KeyToNum(key_press);
if(temp_number2>99)
{
pos=-1;
ClearScreen();
LcdWriteString(0x40,"ERROR:
OVERFLOW");Beep();
temp_number2=0;
}
}
elseif(flag_point==1)
{
LcdWriteString(0x00,"");
count_point++;
KeyDispaly(pos+0x40,key_press);
point_num=KeyToNum(key_press);
for(i=0;ipoint_num=point_num*0.1;
temp_number2=temp_number2+key_press;
}
}
voidPlus(void)
{
count_point=0;
if(flag_plus||flag_minus||flag_multiply||flag_divide||flag_result)return;
pos=pos+2;//空一格
LcdWriteString(0x40,"");
KeyDispaly(pos,PLUS);
pos++;
KeyDispaly(pos,'');
if(tab_num==0)
{
tab_num=1;
flag_plus=1;
}
else
{
//tab_num=0;
//flag_plus=1;
}
}
voidMinus(void)
{
count_point=0;
if(flag_plus||flag_minus||flag_multiply||flag_divide||flag_result)return;
pos=pos+2;//空一格
LcdWriteString(0x40,"");
KeyDispaly(pos,MINUS);
pos++;
KeyDispaly(pos,'');
if(tab_num==0)
{
tab_num=1;
flag_minus=1;
}
els