用的是普中的开发板,下面是程序:#include <reg52.h> #define uchar unsigned char #define uint unsigned int #define ulong unsigned long
sbit LcdEn_P = P2^5; // 1602液晶的EN管脚 sbit LcdRw_P = P2^6; // 1602液晶的RW管脚 sbit LcdRs_P = P2^7; // 1602液晶的RS管脚
ulong num1; // 运算数1 ulong num2; // 运算数2 ulong num3; // 计算结果 uchar cal; // 运算符号,1加,2减,3乘,4除 uchar num1_flag; // 运算数1的输入标志 uchar num2_flag; // 运算数2的输入标志
/*********************************************************/ // 毫秒级的延时函数,time是要延时的毫秒数 /*********************************************************/ void DelayMs(uint time) { uint i,j; for(i=0;i<time;i++) for(j=0;j<112;j++); }
/*********************************************************/ // 1602液晶写命令函数,cmd就是要写入的命令 /*********************************************************/ void LcdWriteCmd(uchar cmd) { LcdRs_P = 0; LcdRw_P = 0; LcdEn_P = 0; P0=cmd; DelayMs(2); LcdEn_P = 1; DelayMs(2); LcdEn_P = 0; }
/*********************************************************/ // 1602液晶写数据函数,dat就是要写入的数据 /*********************************************************/ void LcdWriteData(uchar dat) { LcdRs_P = 1; LcdRw_P = 0; LcdEn_P = 0; P0=dat; DelayMs(2); LcdEn_P = 1; DelayMs(2); LcdEn_P = 0; }
/*********************************************************/ // 1602液晶初始化函数 /*********************************************************/ void LcdInit() { LcdWriteCmd(0x38); // 16*2显示,5*7点阵,8位数据口 LcdWriteCmd(0x0C); // 开显示,不显示光标 LcdWriteCmd(0x06); // 地址加1,当写入数据后光标右移 LcdWriteCmd(0x01); // 清屏 }
/*********************************************************/ // 液晶光标定位函数 /*********************************************************/ void LcdGotoXY(uchar line,uchar column) { // 第一行 if(line==0) LcdWriteCmd(0x80+column); // 第二行 if(line==1) LcdWriteCmd(0x80+0x40+column); }
/*********************************************************/ // 液晶输出字符串函数 /*********************************************************/ void LcdPrintStr(uchar *str) { while(*str!='\0') LcdWriteData(*str++); }
/*********************************************************/ // 液晶输出数字 /*********************************************************/ void LcdPrintNum(uchar num) { LcdWriteData(num+0x30); }
/********************************************************** 矩阵键盘扫描程序. 如果扫描到有按键按下,则返回按键值,返回值情况如下所示: ------------------------------------------------------------- | 第1列 第2列 第3列 第4列 | |第1行 1 2 3 10 | |第2行 4 5 6 11 | |第3行 7 8 9 12 | |第4行 13 0 14 15 | ------------------------------------------------------------ 如果扫描不到有按键按下,则返回99 **********************************************************/ uchar KeyScanf() { uchar ret,temp1,temp2;
P1=0x0f; if(P1!=0x0f) { DelayMs(15); if(P1!=0x0f) { temp1=P1; // 判断出是哪一行按键按下 P1=0xf0; DelayMs(5); temp2=P1; // 判断出是哪一列按键被按下 ret=temp1|temp2; // 通过行和列的值,确定是哪个按键被按下 switch(ret) { case 0xe7: return 1; case 0xd7: return 2; case 0xb7: return 3; case 0x77: return 10;
case 0xeb: return 4; case 0xdb: return 5; case 0xbb: return 6; case 0x7b: return 11;
case 0xed: return 7; case 0xdd: return 8; case 0xbd: return 9; case 0x7d: return 12;
case 0xee: return 13; case 0xde: return 0; case 0xbe: return 14; case 0x7e: return 15; } return ret; } } return 99; }
/*********************************************************/ // 主函数 /*********************************************************/ void main() { uchar ret; uchar i;
LcdInit();
while(1) { LcdWriteCmd(0x01); // 清除屏幕显示 LcdWriteCmd(0x0f); // 开启光标闪烁 num1=0; // 运算数1 清零 num2=0; // 运算数2 清零 num3=0; // 计算结果 清零 cal=0; // 运算符号 清零 i=0; // 临时变量 清零 num1_flag=0; // 运算数1输入标志 清零 num2_flag=0; // 运算数2输入标志 清零
while(1) { ret=KeyScanf(); // 读取矩阵键盘的扫描结果
if(ret!=99) // 返回值不等于99,说明有按键按下了 { DelayMs(20); ret=KeyScanf(); // 读取矩阵键盘的扫描结果
if(ret!=99) { /*检测到的是按下数字*/ if(ret<10) { if(cal==0) // 如果cal的值为0,说明现在在输入运算数1 { if(num1<1000) // 限制运算数1的大小小于10000 { LcdPrintNum(ret); //将按下的数字键刷新显示 num1=num1*10+ret; // 把运算数1放大10倍 num1_flag=1; // 将运算数1的标志变量num1_flag置1,说明运算数1已输入 } } else // 如果cal的值不为0,说明现在在输入运算数2 { if(num2<1000) // 限制运算数2的大小小于10000 { LcdPrintNum(ret); // 将按下的数字键显示 num2=num2*10+ret; // 把运算数2放大10倍 num2_flag=1; // 将运算数2的标志变量num2_flag置1,说明运算数2已输入 } } }
/*检测到的是按下加号*/ if(ret==10) { if(cal==0) // 判断是否是第一次输入计算符号 { if(num1_flag==0) // 判断运算数1是否还未输入 { LcdPrintNum(0); // 如果是的话,在液晶显示数字0 num1=0; // 给运算数1一个计算初值0 } cal=1; // 将运算符变量改为1,代表即将进行加法运算 LcdWriteData('+'); // 把加法运算符号显示到屏幕上 } }
/*检测到的是按下减号*/ if(ret==11) { if(cal==0) // 判断是否是第一次输入计算符号 { if(num1_flag==0) // 判断运算数1是否还未输入 { LcdPrintNum(0); // 如果是的话,在液晶上面显示0 num1=0; // 给运算数1一个计算初值0 } cal=2; // 将运算符变量改为2,代表即将进行减法运算 LcdWriteData('-'); // 把减法运算符号显示到屏幕上 } }
/*检测到的是按下乘号*/ if(ret==12) { if(cal==0) // 判断是否是第一次输入计算符号 { if(num1_flag==0) // 判断运算数1是否还未输入 { LcdPrintNum(0); // 如果是的话,在液晶上面显示0 num1=0; // 给运算数1一个计算初值0 } cal=3; // 将运算符变量改为3,代表即将进行乘法运算 LcdWriteData('*'); // 把乘法运算符号显示到屏幕上 } }
/*检测到的是按下除号*/ if(ret==15) { if(cal==0) // 判断是否是第一次输入计算符号 { if(num1_flag==0) // 判断运算数1是否还未输入 { LcdPrintNum(0); // 如果是的话,在液晶上面显示0 num1=0; // 给运算数1一个计算初值0 } cal=4; // 将运算符变量改为4,代表即将进行除法运算 LcdWriteData('/'); // 把除法运算符号显示到屏幕上 } }
/*检测到的是按下清除键*/ if(ret==13) { break; // 退出当前的while循环 }
/*检测到的是按下等于号*/ if(ret==14) { if(num2_flag==0) // 判断运算数2是否还未输入 { LcdPrintNum(0); // 如果是的话,在液晶上面显示0 num2=0; // 给运算数2一个计算初值0 }
switch(cal) // 根据cal这个变量的不同值,采取不同的四则运算 { /*加法运算*/ case 1: LcdGotoXY(1,15); // 定位到液晶的第2行最后一列 LcdWriteCmd(0x04); // 光标左移 num3=num1+num2; // 计算结果 if(num3==0) // 如果计算结果为0 { LcdPrintNum(0); // 在屏幕上显示0 } while(num3!=0) // 显示计算结果 { LcdPrintNum(num3%10); num3=num3/10; } LcdWriteData('='); // 显示等于号 LcdWriteCmd(0x06); // 光标右移 break;
/*减法运算*/ case 2: LcdGotoXY(1,15); // 定位到液晶的第2行最后一列 LcdWriteCmd(0x04); // 光标左移
if(num1>num2) { num3=num1-num2; // 计算结果 while(num3!=0) // 显示计算结果 { LcdPrintNum(num3%10); num3=num3/10; } } else if(num1<num2) { num3=num2-num1; // 计算结果 while(num3!=0) // 显示计算结果 { LcdPrintNum(num3%10); num3=num3/10; } LcdWriteData('-'); // 显示负号 } else { LcdPrintNum(0); // 显示数字0 }
LcdWriteData('='); // 显示等于号 LcdWriteCmd(0x06); // 光标右移 break;
/*乘法运算*/ case 3: LcdGotoXY(1,15); // 定位到液晶的第2行最后一列 LcdWriteCmd(0x04); // 光标左移 num3=num1*num2; // 计算结果 if(num3==0) // 如果计算结果为0 { LcdPrintNum(0); // 在屏幕上显示0 } while(num3!=0) // 显示计算结果 { LcdPrintNum(num3%10); num3=num3/10; } LcdWriteData('='); // 显示等于号 LcdWriteCmd(0x06); // 光标右移 break;
/*除法运算*/ case 4: if(num2!=0) { LcdGotoXY(1,15); // 定位到液晶的第2行最后一列 LcdWriteCmd(0x04); // 光标左移 num3=(ulong)(((float)num1/num2)*1000); // 计算结果(放大了1000倍)
if(num1<num2) // 如果是小数除以大数 { num3=num3+1000;// 先给计算结果加1000 }
while(num3!=0) // 显示计算结果 { LcdPrintNum(num3%10); num3=num3/10; i++; if(i==3) // 显示小数点 { LcdWriteData('.'); } }
if(num1<num2) // 如果是小数除以大数 { LcdGotoXY(1,11); // 把之前加的1000给清除 LcdPrintNum(0); }
LcdWriteData('='); // 显示等于号 LcdWriteCmd(0x06); // 光标右移 break; } else // 如果除数位0,显示“ERROR!” { LcdGotoXY(1,10); LcdPrintStr("ERROR!"); } } LcdWriteCmd(0x0C); // 光标不闪烁 while(KeyScanf()!=13); // 计算后,只能通过按下清除键,才能进入新一轮的计算 break; }
DelayMs(10); // 去除按键按下的抖动 while(KeyScanf()!=99); // 等待按键释放 DelayMs(10); // 去除按键松开的抖动 } } } } }
|