您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 电子设计/PCB > 简易计算器(1602加矩阵键盘)
一、原理图:二、程序#includereg51.h//包含单片机寄存器的头文件#includeintrins.h//包含_nop_()函数定义的头文件#includemath.hsbitRS=P2^0;//寄存器选择位,将RS位定义为P2.0引脚sbitRW=P2^1;//读写选择位,将RW位定义为P2.1引脚sbitE=P2^2;//使能信号位,将E位定义为P2.2引脚sbitBF=P1^7;//忙碌标志位,#defineNO_KEY_PRESS0xff/********************************************************************************************************/unsignedcharcodetab[]={0xb7,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,0xdb,0xbb};unsignedcharcodenum[]={0123456789};unsignedlongnum1,num2,alg;unsignedcharflag;voiddelay1ms(){unsignedchari,j;for(i=0;i10;i++)for(j=0;j15;j++);}/********************************************************************************************************/voiddelay(unsignedcharn){unsignedchari;for(i=0;in;i++)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;//将忙碌标志电平赋给resultE=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;//将数据送入P1口,即写入指令或地址_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发生正跳变,所以应先置0P1=y;//将数据送入P0口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_();//空操作四个机器周期,给硬件反应时间E=1;//E置高电平_nop_();_nop_();_nop_();_nop_();//空操作四个机器周期,给硬件反应时间E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:对LCD的显示模式进行初始化设置***************************************************/voidLcdInitiate(void){delay(15);//延时15ms,首次写指令时应给LCD一段较长的反应时间WriteInstruction(0x38);//显示模式设置:16×2显示,5×7点阵,8位数据接口delay(5);//延时5msWriteInstruction(0x38);delay(5);WriteInstruction(0x38);delay(5);WriteInstruction(0x0c);//显示模式设置:显示开,有光标,光标闪烁delay(5);WriteInstruction(0x06);//显示模式设置:光标右移,字符不移delay(5);WriteInstruction(0x01);//清屏幕指令,将以前的显示内容清除delay(5);}unsignedcharkeyscan()//键盘扫描,返回扫描值{unsignedchartemp1,temp2,key;P0=0xf0;if(P0!=0xf0){delay(10);if(P0!=0xf0){temp1=P0;P0=0x0f;_nop_();_nop_();_nop_();temp2=P0;key=temp1|temp2;while(P0!=0x0f);returnkey;}}returnNO_KEY_PRESS;}unsignedcharkey_inquiry()//对键盘扫描值译码并显示{unsignedchari,key;key=keyscan();if(key!=NO_KEY_PRESS){if(flag)//按等于号若再次计算则将之前的数值清零{WriteInstruction(0x01);delay(5);flag=0;}switch(key){case0x7e:WriteData('+');return'+';case0x7d:WriteData('-');return'-';case0x7b:WriteData('*');return'*';case0x77:WriteData(0xfd);return'/';case0xd7:WriteAddress(0x40);WriteData('=');return'=';case0xe7:WriteInstruction(0x01);num1=0;num2=0;break;//CEdefault:break;}for(i=0;i10;i++){if(key==tab[i]){WriteData(num[i]);returni;}}}returnNO_KEY_PRESS;}voidcount()//对计算进行处理,并显示计算后的结果{unsignedcharkey,i=0,a[9];unsignedlongnum0;key=key_inquiry();if((key=='+')||(key=='-')||(key=='*')||(key=='/')){num2=num1;num1=0;alg=key;}if(key10){num1=num1*10+key;}if(key=='='){WriteAddress(0x41);switch(alg)//对算法进行处理{case'+':num0=num1+num2;break;case'-':if(num2num1)num0=(num2-num1);if(num2num1){WriteData('-');num0=num1-num2;}break;case'*':num0=(num1*num2);break;case'/':if(num10)num0=(num2/num1);elseWriteData('e');break;default:num0=0;break;}//显示计算结果if(0==num0){if(0!=alg)WriteData('0');elsenum0=num1;}while(num00){i++;a[i]=num0%10;//WriteData(num[num0%10]);num0=num0/10;}for(;i0;i--){WriteData(num[a[i]]);}num1=0;num2=0;alg=0;flag=1;}}voidmain(void)//主函数{num1=0;num2=0;LcdInitiate();//调用LCD初始化函数WriteAddress(0x00);while(1){count();}}说明:1、能计算加减乘除2、减法结果可以为负数3、最大可计算42949672954、不能检测溢出,不能计算负数,不能组合运算,不能算小数
本文标题:简易计算器(1602加矩阵键盘)
链接地址:https://www.777doc.com/doc-5752669 .html