0.png (24.28 KB, 下載次數: 33)
下載附件
2019-10-13 18:37 上傳
用的是普中的開發板,下面是程序:#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); // 去除按鍵松開的抖動 } } } } }
|