#include
#include
#include
#include
unsigned char code Error[]={"error"};
unsigned char code Systemerror[]={"system error"};
unsigned char code Lcd[]={"lcd calculate"};
char str[16];
sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;
sbit BF=P0^7;
/***********************
函数功能:延时1ms
***********************/
void delay1ms()
{
unsigned char i,j;
for (i=0;i<10;i++)
for (j=0;j<33;j++)
;
}
/************************
函数功能:延时n毫秒
入口参数:n
************************/
void delaynms(unsigned char n)
{
unsigned char i;
for (i=0;i delay1ms(); } /************************************ 函数功能:判断液晶模块的忙碌状态 返回值:result。result=1,忙碌;result=0,不忙。 ************************************/ bit BusyTest(void) { bit result; RS=0; //根据规定,RS为低电平、RW为高电平时,可以读状态 RW=1; E=1; //E=1,才允许读/写 _nop_(); _nop_(); _nop_(); _nop_(); result=BF; //将忙碌标志电平赋给result E=0; return result; } /************************************* 函数功能:将模式设置指令或显示地址写入液晶模块 入口参数:dictate **************************************/ void WriteInstruction(unsigned char dictate) { while(BusyTest()==1); //如果忙就等待 RS=0; //根据规定,RS和R/W同为低电平时,可以写入指令 RW=0; E=0; _nop_(); _nop_(); P0=dictate; //将数据送入P0口,即写入指令或地址 _nop_(); _nop_(); _nop_(); _nop_(); E=1; //E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); E=0; } /***************************************** 函数功能:指定字符显示的实际地址 入口参数:x,y *****************************************/ void WriteAddress(unsigned char x,unsigned char y) { unsigned char temp; if(x==0) { switch(y) { case 0:temp=0x00; break; case 1:temp=0x01; break; case 2:temp=0x02;break; case 3:temp=0x03;break; case 4:temp=0x04;break; case 5:temp=0x05;break; case 6:temp=0x06;break; case 7:temp=0x07;break; case 8:temp=0x08;break; case 9:temp=0x09;break; case 10:temp=0x0a;break; case 11:temp=0x0b;break; case 12:temp=0x0c;break; case 13:temp=0x0d;break; case 14:temp=0x0e;break; case 15:temp=0x0f;break; } } if(x==1) { switch(y) { case 0:temp=0x40;break; case 1:temp=0x41;break; case 2:temp=0x42;break; case 3:temp=0x43;break; case 4:temp=0x44;break; case 5:temp=0x45;break; case 6:temp=0x46;break; case 7:temp=0x47;break; case 8:temp=0x48;break; case 9:temp=0x49;break; case 10:temp=0x4a;break; case 11:temp=0x4b;break; case 12:temp=0x4c;break; case 13:temp=0x4d;break; case 14:temp=0x4e;break; case 15:temp=0x4f;break; } } WriteInstruction(temp|0x80); //显示位置的确定方法规定为“80H+地址码x”} /***************************************** 函数功能:将数据(字符的标准ASCII码)写入液晶模块 入口参数:y *****************************************/ void WriteData (unsigned char y) { while(BusyTest()==1); RS=1; //RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0; P0=y; //将数据送入P0口,即将数据写入液晶模块_nop_(); _nop_(); _nop_(); _nop_(); E=1; _nop_(); _nop_(); _nop_(); _nop_(); E=0; //当E由高电平跳变成低电平时,液晶模块开始执行指令 } /***************************************** 函数功能:对LCD的显示模式进行初始化设置 *****************************************/ void LcdInitiate(void) { delaynms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间 WriteInstruction(0x38); //显示模式设置 delaynms(5); WriteInstruction(0x38); delaynms(5); WriteInstruction(0x38); delaynms(5); WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁 delaynms(5); WriteInstruction(0x06); //显示模式设置:光标右移,字符不移 delaynms(5); WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除 delaynms(5); } /*************************************** 函数功能:显示字符串 ***************************************/ void display_error() { unsigned char i; WriteAddress(0,0); i=0; while(Error[i]!='\0') { WriteData(Error[i]); i++; delaynms(100); } } void display_systemerror() { unsigned char i; WriteAddress(0,0); i=0; while(Systemerror[i]!='\0') { WriteData(Systemerror[i]); i++; delaynms(100); } } void display_lcd() { unsigned char i; WriteAddress(0,0); i=0; while(Lcd[i]!='\0') { WriteData(Lcd[i]); i++; delaynms(100); } } /*************************** 函数功能:按键判断 **************************/ bit judge() { unsigned char keycode; P1=0x0f; keycode=P1; if(keycode==0x0f) return(0); else return(1); } /***************************** 函数功能:键盘扫描 *****************************/ unsigned char scan() { unsigned char keycode,keyscan; keyscan=0xef; while(keyscan!=0xff) { P1=keyscan; keycode=P1; if((keycode&0x0f)!=0x0f) break; keyscan=(keycode<<1)|0x0f; } keycode=~keycode; return(keycode); } /******************************* 函数功能:扫描键盘返回值 ******************************/ unsigned char Key_Num() { unsigned char keycode; unsigned char yong; if(judge()) { delaynms(20); if(judge()) { keycode=scan(); while(judge()); switch(keycode) { case 0x11:yong='7';break; case 0x12:yong='4';break; case 0x14:yong='1';break; case 0x18:yong=0;break; case 0x21:yong='8';break; case 0x22:yong='5';break; case 0x24:yong='2';break; case 0x28:yong='0';break; case 0x41:yong='9';break; case 0x42:yong='6';break; case 0x44:yong='3';break; case 0x48:yong='=';break; case 0x81:yong='/';break; case 0x82:yong='*';break; case 0x84:yong='-';break; case 0x88:yong='+';break; default:display_systemerror() ; } return(yong); } } else return(0xff); } /************************************** itoa函数定义 *********************************/ unsigned char itoa(long int num) { unsigned char i,j,L; unsigned char temp[16]; for(i=0;num!=0;i++) { temp[i]=num%10+48; num=num/10; } L=i; if(i>16) { display_systemerror(); } for(j=0;j<=L;j++) { str[j]=temp[i]; i--; } return(L); } /***************************************** 函数功能:主函数 ****************************************/ void main() { long int a; long int b; unsigned char flag; unsigned char sign; unsigned char i,j,s,x; unsigned char num; unsigned char fgh; unsigned char temp[16]; LcdInitiate(); display_lcd(); delaynms(20); WriteInstruction(0x01); flag=1; while(1) { num=Key_Num(); if(num!=0xff) { if(fgh==1) { WriteInstruction(0x01); fgh=0; } if((num!='+')&&(num!='-')&&(num!='*')&&(num!='/')&&(num!='.')&&(num!='=')) { if(flag==1) { a=a*10+num-48; } else { b=num-48+b*10; } } if(num==0) { i=0; flag=1; a=0;b=0; WriteInstruction(0x01); } if((num=='+')||(num=='-')||(num=='*')||(num=='/')) { flag=0; switch(sign) { case '+':a=a+b;break; case '-':a=a-b;break; case '*':a=a*b;break; case '/': {if(b!=0) { a=a/b;break; } else { WriteInstruction(0x01); flag=1; WriteAddress(0,1); display_error(); delaynms(40); WriteInstruction(0x01); break; } } default:break; } sign=num; b=0; } if(num=='=') { flag=1; switch(sign) { case '+':a=a+b; break; case '-':a=a-b; break; case '*':a=a*b; break; case '/':a=a/b; break; default:break; } temp[i]=num; WriteAddress(0,i); WriteData(num); for(s=0;s<16;s++) temp[s]=0; s=0; //WriteAddress(1,8); //WriteData(a+48); x=itoa(a); //函数转换 WriteAddress(1,1); while(s<=x) { WriteData(str[s]); s++; delaynms(100); } sign=0;a=b=0;j=0; for(s=0;s<16;s++) str[s]=0; s=0; fgh=1; i=0; } if(i<16) { if(num!='=') { if((i==1)&& (temp[0]=='0') )//如果第一个字符是0,判读第二个字符 { temp[0]=num; //如果是1-9数字,说明0没有用,则直接替换第一位0 WriteAddress(0,0);//输出数据 WriteData(num); } else { temp[i]=num; WriteAddress(0,i);//输出数据 WriteData(num); i++; //输入数值累加 } } } else { i=0; WriteInstruction(0x01); } } } }