命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。114X4矩阵键盘实现的计算器一、功能实现基本的两个整数加、减、乘、除运算,采用4X4矩阵键盘输入数据,结果由LCD1602显示。可以显示负数结果,并且还具有清除功能。该软件基于普中科技的HC6800_EM3V2.2平台,微处理器为STC89C52单片机。二、硬件电路图硬件各个部分的电路图如下:1、STC89C52单片机电路图2、LCD1602显示电路图命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。223、矩阵键盘电路图P1.7P1.6P1.5P1.4P1.3P1.2P1.1P1.0012345678910(+)11(-)12(*)13(/)14(=)15(CLR)三、软件程序1、LCD1602驱动程序(1)LCD1602.c#includereg52.h#includeintrins.hsbitLCD_RS=P2^6;sbitLCD_RW=P2^5;sbitLCD_EN=P2^7;命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。33#definedelayNOPs();{_nop_();_nop_();_nop_();_nop_();};//延时函数,延时大约1ms乘以nvoidDelayNms(unsignedintn){unsignedcharx;while(n--){for(x=0;x250;x++){_nop_();_nop_();_nop_();_nop_();}}}/***************************************************************************//**//*检查LCD忙状态*//*返回值为1时,表示忙,等待。返回值为0时,表示闲,可以写入指令与数据。*//*读状态:RS=L,RW=H,E=H,D0-D7=状态字*//**//***************************************************************************/bitLcd1602_is_busy(void){bitresult;LCD_RS=0;LCD_RW=1;LCD_EN=1;delayNOPs();//保证使能脉冲的宽度result=(bit)(P0&0x80);LCD_EN=0;return(result);}/*******************************************************************//**//*写指令到LCD*/命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。44/*RS=L,RW=L,E=高脉冲,D0-D7=指令码*//**//*******************************************************************/voidLcd_Write_Command(unsignedcharcmd){while(Lcd1602_is_busy());LCD_RS=0;LCD_RW=0;LCD_EN=0;P0=cmd;delayNOPs();//保证使能脉冲的宽度LCD_EN=1;delayNOPs();LCD_EN=0;}/*******************************************************************//**//*写显示数据到LCD*//*RS=H,RW=L,E=高脉冲,D0-D7=数据*//**//*******************************************************************/voidLcd_Write_Data(unsignedchardat){while(Lcd1602_is_busy());LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;delayNOPs();LCD_EN=1;delayNOPs();LCD_EN=0;}/*******************************************************************//**//*LCD初始化设定*//**//*******************************************************************/voidInit_Lcd1602(void){DelayNms(15);Lcd_Write_Command(0x38);//设置成:16*2显示,5*7点阵,8位数据接口命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。55DelayNms(5);//Lcd_Write_Command(0x08);//显示关闭//DelayNms(5);Lcd_Write_Command(0x0C);//显示开,关光标DelayNms(5);Lcd_Write_Command(0x06);//移动光标,输入方式从左到右DelayNms(5);Lcd_Write_Command(0x01);//清除LCD的显示内容,数据指针清零,将光标撤回液晶显示屏的左上方DelayNms(5);}(2)LCD1602.hvoidLcd_Write_Command(unsignedcharcmd);voidLcd_Write_Data(unsignedchardat);voidInit_Lcd1602(void);voidDelayNms(unsignedintn);2、矩阵键盘驱动程序(1)4X4KeyPad.c#includeSTC89C5xRC.h#includeLCD1602.h//要用到延时函数voidDelayNms(unsignedcharn);#definekeyP1unsignedcharval=16;//获取的键值#defineKEY_NULL0xFF//后来加上的//键盘扫描函数unsignedcharkey_scan(void){unsignedcharstate,KeyTemp;key=0x0F;if(key!=0x0F)//如果有按键按下{state=key;//记录第一次按键状态DelayNms(10);//延时去抖if(key==state)//判断按键状态是否和第一次一致{key=0x0F;//测试列,该行可屏蔽掉switch(key)命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。66{case(0x07):KeyTemp=0;break;case(0x0B):KeyTemp=1;break;case(0x0D):KeyTemp=2;break;case(0x0E):KeyTemp=3;break;}key=0xF0;//测试行switch(key){case(0x70):val=KeyTemp+0;break;case(0xB0):val=KeyTemp+4;break;case(0xD0):val=KeyTemp+8;break;case(0xE0):val=KeyTemp+12;break;}while(key!=0xF0);//等待松开按键}elsereturn(KEY_NULL);}elsereturn(KEY_NULL);//elsekey=0xFF;//释放键盘总线}(2)4X4KeyPad.hexternunsignedcharkey_scan(void);externunsignedcharval;#defineKEY_NULL0xFF3、计算器计算和显示程序(1)caculatinganddisplaying.c#includestdio.h//sprintf语句用到#includeLCD1602.h#include4X4KeyPad.hunsignedcharcodetable1[]={0123456789+-*/=C};bitnumber_key=0;//数字键bitadd_key=0;//加法键+bitsub_key=0;//减法键-bitmultiply_key=0;//乘法键*bitdivision_key=0;//除法键/命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。77bitequal_key=0;//等于键=bitclear_key=0;//清除键doublea=0,b=0,s=0;//a为计算的第一个数,b为第二个数,s为计算结果//必须定义为浮点,否则不能够保证计算精度//识别按键,置标记符voidKey_Recognition(void){if(key_scan()!=KEY_NULL)//有按键按下时才置标志位和显示{if(val=9)number_key=1;if(val==10)add_key=1;if(val==11)sub_key=1;if(val==12)multiply_key=1;if(val==13)division_key=1;if(val==14)equal_key=1;if(val==15)clear_key=1;Lcd_Write_Data(table1[val]);//显示按键对应的字符}}//计算被计算的两个数GetsthenumberoftwotobecalculatedvoidGet_Parameters_for_calculation(void){if(equal_key!=1)//没有按等号键才进入{if((add_key||sub_key||multiply_key||division_key)!=1)//没有按下运算键(+-*/){if(number_key==1)//是数字键{a=a*10+val;//a为运算的第一个数number_key=0;}}else//按下运算键(+-*/){if(number_key==1){b=b*10+val;//b为运算的第二个数number_key=0;}}命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。88}}//计算结果voidCalculate_Result(void){if(equal_key==1)//只有按等号键才能计算{if(add_key==1)//加法s=a+b;if(sub_key==1)//减法s=a-b;if(multiply_key==1)//乘法s=a*b;if(division_key==1)//除法s=a/b;}}voidDisplay_Result(void){unsignedchari=0;//显示字符的指针unsignedcharresult[16]=;//待显示的字符计算结果if(equal_key==1)//只有按等于键才显示{equal_key=0;sprintf(result,%.4f,s);//浮点数的默认有效位是小数点后6位,这里设置为4位//sprintf(&temp1[0],%f,a);Lcd_Write_Command(0x80+0x40);//结果在第二行显示while(result[i]!='\0'){Lcd_Write_Data(result[i]);i++;}}}//清除显示voidClearScreen(void){if(clear_key==1)//只有按清除键才能清除{Lcd_Write_Command(0x01);//LCD清屏指令,把光标撤回到显示器的左上命运如同手中的掌纹,无论多曲折,终掌握在自己手中。你今天的日积月累,终会变成别人的望尘莫及。99number_key=add_key=sub_key=multiply_key=