//基于stc89c52rc,使用LCD1602显示,4*4矩阵键盘读取
//单片机最小系统板,矩阵键盘,lcd功能板原理图见以前的文章
//功能:
//1.两个数字加减乘除
//2.除法运算时可以自定义保留小数位数
//3.定时器扫描矩阵键盘
//4.外部中断清屏
//5.错误输入时会有提示Error
//6.运算结束后可以将运算结果转化为二进制或十六进制
//仅为主函数部分,实现以上功能需调用其他功能函数部分,见以前发的文章
//调用时自己创建.h文件,设置函数外部可调用
//有问题可以评论或私信
//学习自b站江科大自化协,该部分为原创
#include#include "LCD1602.H" #include "TIMEROFKEY.H" void timer_Initial() { TMOD &= 0xF0; TMOD |= 0x01; TF0=0; TR0=1; TH0=0xFC; TL0=0x18; ET0=1; EA=1; PT0=0; } void timer_main() interrupt 1 { static unsigned int Count; TH0=0xFC; TL0=0x18; Count++; if(Count>=10) { Count=0; KEY_main(); } } unsigned char IspirmeofInterupt=1; void Interupt_Init() //按键清屏 { IT0=0; EX0=1; EA=1; } void Interupt() interrupt 0 { IspirmeofInterupt=0; } unsigned char lenofresult(int result) //输出计算结果的位数 { unsigned char len=0; if(result<0) { result=-result; } do { result/=10; len++; }while(result>0); return len; } int Result(unsigned char *a,unsigned char lenofChar,int* result,double* result1) { int num1=0; //运算函数,把字符串里的计算式转化为一般计算式进行计算 int num2=0; char mode; unsigned char i; unsigned char isprime=0; //isprime判断运算合法性,通过指针返回最终计算结果 for(i=0;i ='0'&&a[i]<='9') { num1*=10; num1+=(a[i]-'0'); }else { num2=num1; num1=0; mode=a[i]; } } if(a[0]=='-') { num2=-num2; //解决了第一个输入数为负数计算错误的问题 } switch (mode) { case'+':*result=num2 + num1; isprime=1;break; case'-':*result=num2 - num1; isprime=1;break; case'*':*result=num2 * num1; isprime=1;break; case'/': if(num1==0) { isprime=0; break; } else { *result=num2/num1; *result1=(double)num2/num1; isprime=2; } } if(a[lenofChar-1]==mode) { isprime=0; //最后一位为运算符则为不合法运算 } return isprime; } void calculate(void) { unsigned char temp[20]; unsigned char button[16]= //按键值对应字符 { '1','2','3','+', '4','5','6','-', '7','8','9','*', '?','0','=','/', }; unsigned char key; unsigned char i=16; unsigned char j=0; unsigned char len; unsigned char isprime; double result1; int result; do { if(IspirmeofInterupt==0) //如果中断,则重置数组 { LCD_Initial(); i=16,j=0; IspirmeofInterupt=1; } key=KEY_Back(); //读取按键值,把对应字符打印在屏幕上 if(key!=0) { LCD_ShowChar(1,i++,button[key-1]); if(key!=15) { LCD_WriteCommand(0x18); //每打印一个字符屏幕右移1,解决了最终输出有空格的问题 } temp[j++]=button[key-1]; //把输入的字符存入数组中,最终按下‘=’时把构成的字符串运算式 } //交给运算函数,转化为一般运算式进行运算 }while(key!=15); isprime=Result(temp,j-1,&result,&result1); if(isprime==1) //整数型输出 { len=lenofresult(result); if(result>=0) { LCD_ShowSignedNum(2,i-len,result,len); } else { LCD_ShowSignedNum(2,i-len-1,result,len); } } else if(isprime==0) { LCD_ShowString(2,i-6,"Error!"); } else if(isprime==2) { char len1; char n=1; do { len1=lenofresult(result); LCD_ShowFloat(2,i-len1-1-n,result1,result,len1,n); do { key=KEY_Back(); }while(!key); n++; }while(n<5); LCD_ShowString(2,i-9,"Too Long!"); } do { unsigned char n=1; key=KEY_Back(); if(key==13&&n==1) { LCD_Initial(); LCD_ShowSignedNum(1,16-len,result,len); LCD_ShowHexNum(2,12,result,2); do{key=KEY_Back();}while(!key); LCD_Initial(); LCD_ShowSignedNum(1,16-len,result,len); LCD_ShowBinNum(2,6,result,8); n++; do{key=KEY_Back();}while(!key); } // if(key!=13) // { // break; // } if(IspirmeofInterupt==0) { IspirmeofInterupt=1; break; } }while(!key); //计算结束,按任意键继续 } void main() { Interupt_Init(); timer_Initial(); LCD_Initial(); LCD_ShowString(1,1,"Welcome to use"); do{}while(!KEY_Back()); while(1) { LCD_Initial(); calculate(); } }



