? 由于本文較早,這里推薦一下近期剛優(yōu)化的:【優(yōu)化】51單片機計算器(LCD1602液晶顯示)_Gxtoeilee的博客-CSDN博客
?文章來源地址http://www.zghlxwxcb.cn/news/detail-500887.html
1 設(shè)計目標(biāo)
設(shè)計可選模式的計算器?
2 主要功能
功能一:可選兩種計算模式,模式一為四則運算,模式二為擴展內(nèi)容;
功能二:除法的計算結(jié)果保留到小數(shù)點后四位;
功能三:除數(shù)為0時報錯。
3 硬件部分講解
51單片機,導(dǎo)線,矩陣鍵盤,獨立按鍵,LCD1602液晶顯示屏
?
? ? ? ? ? ? ? ? ? ? ? ? ?圖1? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖2
??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖3? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖4
?文章來源:http://www.zghlxwxcb.cn/news/detail-500887.html
??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖5? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖6
圖7
圖8
圖9
圖10
圖11
圖1為矩陣鍵盤模塊。
圖2為獨立按鍵模塊。K1連接P2_0,K2連接P2_1。
圖3為LCD1602接口??刂菩Ч缦拢?/p>
? ? RW:P2_5控制;
? ? RS:P2_6控制;
? ? EN:P2_7控制;
? ? D0—D7:P0_0—P0_7。
圖4為矩陣鍵盤由P1組控制的效果。
圖5為LCD1602顯示代碼。
圖6為LCD1602顯示位置及代碼。
圖7為LCD1602的引腳接口說明。
圖8為LCD1602的寫操作時序圖。
圖9為LCD1602的時序參數(shù)。
圖10為計算器計算按鍵,對應(yīng)矩陣鍵盤。
圖11為計算器模式選擇按鍵,對應(yīng)獨立按鍵。
?
4 軟件流程及代碼實現(xiàn)
?
4.1主要代碼說明
本程序由一個主函數(shù)和六個子函數(shù)組成。子函數(shù)分別為:延時函數(shù)、LCD寫命令函數(shù)、LCD寫數(shù)據(jù)函數(shù)、LCD初始化函數(shù)、模式判定函數(shù)、計算器函數(shù)。
4.1.1 主函數(shù)
主函數(shù)首先調(diào)用LCD初始化函數(shù)對LCD1602顯示屏進行初始化,然后顯示歡迎語句welcome,延時1s后清屏。進入循環(huán)后首先調(diào)用功能判定函數(shù)選擇計算器模式。在設(shè)計之初計劃設(shè)定兩種模式,模式一中為四則運算,模式二中為擴展其他功能,隨后根據(jù)所選模式的返回值進入不同的計算器程序。此處只對模式一進行展示,即四則運算。
void main()
{
uint x;
lcdinit();//LCD1602初始化
for(x=0;x<12;x++)
lcdwrd(wel[x]);//顯示歡迎語句:Welcome
delay(1000);
lcdwrc(0x01);//LCd1602清屏
while(1)
{
MODE();//功能判定函數(shù)
KeyDown();//按鍵判斷函數(shù)
}
}
?
4.1.2 子函數(shù)1
延時函數(shù)為延時x毫秒,主要用于LCD1602的初始化、顯示語句、按鍵消抖。
void delay(unsigned int xms)//延時x毫秒
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=112;j>0;j--);
return;
}
4.1.3 子函數(shù)2
LCD寫命令函數(shù)。RS為寄存器選擇,高電平時選擇數(shù)據(jù)寄存器,低電平時選擇指令寄存器。此處為RS賦低電平選擇指令寄存器。由寫操作時許圖可知,RW可全過程定義為低電平;EN為使能端,由EN和DB0—DB7時序可知,EN首先為低電平,高電平時寫指令,低電平時寫指令完成,液晶模塊執(zhí)行命令。
void lcdwrc(uint c)
{
delay(100);
rs=0;
rw=0;
e=0;
P0=c;
e=1;
delay(100);
e=0;
}
4.1.4 子函數(shù)3
LCD寫數(shù)據(jù)函數(shù)。RS為寄存器選擇,高電平時選擇數(shù)據(jù)寄存器,低電平時選擇指令寄存器。此處為RS賦高電平選擇數(shù)據(jù)寄存器。由寫操作時許圖可知,RW可全過程定義為低電平;EN為使能端,由EN和DB0—DB7時序可知,EN首先為低電平,高電平時寫數(shù)據(jù),低電平時寫數(shù)據(jù)完成,液晶模塊執(zhí)行命令。
void lcdwrd(uint dat) //設(shè)置LCD寫數(shù)據(jù)
{
delay(100);
rs=1;
rw=0;
e=0;
P0=dat;
e=1;
delay(100);
e=0;
rs=0;
}
4.1.5 子函數(shù)4
初始化LCD函數(shù)。固定程序以及定義計算器需要用的變量。
void lcdinit() //初始化LCD
{
delay(150);
lcdwrc(0x38);//寫指令38H
delay(50);
lcdwrc(0x38);//顯示模式設(shè)置
delay(50);
lcdwrc(0x38);
delay(50);
lcdwrc(0x38);//功能設(shè)定指令
lcdwrc(0x08);
lcdwrc(0x01);//清屏
lcdwrc(0x06);//顯示光標(biāo)移動設(shè)置
lcdwrc(0x0c); //顯示開關(guān)控制指令
num=0;//用于判定按鍵是否為“=”或者“歸零”時的變量
fuhao=0;//用于判定是否為運算符號
flag=0;//用于判定運算方式時的變量
a=0;//計算的第一個數(shù)
b=0;//計算的后一個數(shù)
c=0;//計算結(jié)果
x=0;//判定小數(shù)點的變量,暫存c值
k=0;//判定小數(shù)點的變量,小數(shù)點后非零數(shù)個數(shù)
j=0;//顯示ERROR時的循環(huán)用變量
}
4.1.6子函數(shù)5
模式判定函數(shù)。用于顯示選擇的是哪個模式并且返回主函數(shù)值,使主函數(shù)運行相應(yīng)值。此處因我只定義了一個模式,故只有模式1。
void MODE()
{
if(P2_0==0)
{
for(j=0;j<10;j++)
lcdwrd(MODE1[j]);//顯示語句:MODE1
delay(1000);//延時
lcdinit();//重新初始化LCD1602
}
}
4.1.7子函數(shù)6
計算器函數(shù)。該函數(shù)較為復(fù)雜,大致分為按鍵判定、按鍵掃描、實現(xiàn)功能。
按鍵判定使判斷是否有按鍵按下。
按鍵掃描部分是判定哪個鍵被按下。首先對第一列掃描,若掃描結(jié)果為歸零鍵,便會將LCD執(zhí)行清零操作。若掃描到其他按鍵,則顯示對應(yīng)數(shù)字。后面二、三、四列的定義均如此。
計算部分為掃描結(jié)果為“=”鍵時。加法和乘法運算都只需要直接計算即可。計算的結(jié)果是從后往前輸入,這樣便于確定結(jié)果顯示的位置。
減法運算中,程序會先判斷減數(shù)和被減數(shù)的大小關(guān)系,從而確定結(jié)果是否為負(fù)數(shù)。若為負(fù)數(shù),則會顯示負(fù)號。
??? 除法運算時,因為除法中可能會出現(xiàn)小數(shù),所以先將計算結(jié)果乘以10000,然后將結(jié)果循環(huán)除以10,直到為0,每次循環(huán)都會使變量k加1,最后跟據(jù)k的大?。?-4)來確定小數(shù)點的位置,即保留四位小數(shù)。
void KeyDown()//計算器函數(shù)
{
k=0;
P1=0x0f; //0000 11111,行都為低電平0,列都為高電平
if(P1!=0x0f)//P1不為0x0f,則判定為有按鍵被按下
{
delay(100);//消抖
if(P1!=0x0f)//延時后,再次判斷
{
P1=0x0f;//0000 11111,行都為低電平0,列都為高電平
switch(P1)//
{
/********************第一列有按鍵按下*********************/
case 0x07://0000 0111 第一列有按鍵被按下
{
P1=0xf0;//列都為低電平0,行都為高電平1
switch(P1)//判斷哪一行的按鍵被按下
{
case 0x70: num = 1/*S1*/;k=7;break; //0111 0000第一列第一行 數(shù)字7
case 0xb0: num = 5/*S5*/;k=4;break; //1011 0000第一列第二行 數(shù)字4
case 0xd0: num = 9/*S9*/;k=1;break; //1101 0000第一列第三行 數(shù)字1
case 0xe0: num = 13/*S13*/;break; //1110 0000第一列第四行 歸零
}
if(num!=13)//被按下的按鍵不是歸零鍵
{
if(fuhao==0)//fuhao==0,表示第一個數(shù)a,fuhao==1,表示第二個數(shù)b
a=a*10+k;
else
b=b*10+k;
}
lcdwrd(0x30+k);//顯示按下的數(shù),0x30為ASCII碼中數(shù)字組的開頭,0x3k:顯示k,即按下數(shù)字k
if(num==13)//按下的按鍵是清零鍵
{
lcdwrc(0x01); //清屏指令
lcdinit();//重新初始化LCD1602
}
}while(P1!=0xf0);break;//當(dāng)有按鍵被按下時,結(jié)束此次判斷,進行下一次判斷
/********************第二列有按鍵按下*********************/
case 0x0b: //0000 1011 第二列有按鍵被按下
{
P1=0xf0;//行都為高電平1,列都為低電平0
switch(P1)//判斷哪一行有按鍵被按下
{
case 0x70: k=8;break;//第二列第一行 數(shù)字8
case 0xb0: k=5;break;//第二列第二行 數(shù)字5
case 0xd0: k=2;break;//第二列第三行 數(shù)字2
case 0xe0: k=0;break;//第二列第四行 數(shù)字0
}
if(fuhao==0)//fuhao==0,表示第一個數(shù)a,fuhao==1,表示第二個數(shù)b
a=a*10+k;
else
b=b*10+k;
lcdwrd(0x30+k);//顯示按下的數(shù),0x30為ASCII碼中數(shù)字組的開頭,0x3k:顯示k,即按下數(shù)字k
} while(P1!=0xf0);break;//當(dāng)有按鍵被按下時,結(jié)束此次判斷,進行下一次判斷
/********************第三列有按鍵按下*********************/
case 0x0d: //0000 1101 第三列有按鍵被按下
{
P1=0xf0;//行都為高電平1,列都為低電平0
switch(P1)//判斷哪一行有按鍵被按下
{
case 0x70: num=3;k=9;break;//第三列第一行 數(shù)字9
case 0xb0: num=7;k=6;break;//第三列第二行 數(shù)字6
case 0xd0: num=11;k=3;break;//第三列第三行 數(shù)字3
case 0xe0: num=15;break;//第三列第四行 “=”鍵
}
if(num!=15)//按下的鍵不為“=”鍵
{
if(fuhao==0)//fuhao==0,表示第一個數(shù)a,fuhao==1,表示第二個數(shù)b
a=a*10+k;
else
b=b*10+k;
lcdwrd(0x30+k);//顯示按下的數(shù),0x30為ASCII碼中數(shù)字組的開頭,0x3k:顯示k,即按下數(shù)字k
}
/************"="鍵被按下************/
if(num==15)//按下的鍵為=鍵
{
switch(flag)//判斷進行哪種運算
{
/*******加法運算*********/
case 1://加法運算
{
c=a+b;//計算結(jié)果
lcdwrc(0x4f/*第二行末尾位置*/+0x80);//光標(biāo)置于第二行末尾
lcdwrc(0x04);//設(shè)置顯示方式:顯示后指針減一,即前移一位
if(c==0)//若結(jié)果為0
lcdwrd(0x30);//顯示0
while(c!=0)
{
lcdwrd(0x30+c%10);//從后向前顯示最后一位
c=c/10;//去掉最后一位后再循環(huán)顯示
}
lcdwrd(0x3d);//顯示完計算結(jié)果后,顯示“=”
}break;
/*******減法運算*********/
case 2://減法運算
{
if(a>b)//大數(shù)減小數(shù)
c=a-b;
else//小數(shù)減大數(shù)
c=b-a;//計算兩數(shù)相減的絕對值
lcdwrc(0x4f+0x80);//將光標(biāo)置于第二行末尾
lcdwrc(0x04);//設(shè)置顯示方式:顯示后指針減一
if(c==0)//若結(jié)果為零
lcdwrd(0x30);//顯示0
while(c!=0)
{
lcdwrd(0x30+c%10);//從后向前顯示最后一位
c=c/10;//去掉最后一位后再循環(huán)顯示
}
if(a<b)//若結(jié)果為負(fù)數(shù)
lcdwrd(0x2d);//ASCII中的“-”,顯示負(fù)號
lcdwrd(0x3d);//顯示=
}break;
/*******乘法運算*********/
case 3://乘法運算
{
c=a*b; //計算結(jié)果
lcdwrc(0x4f+0x80);//光標(biāo)置于第二行末尾
lcdwrc(0x04);//顯示設(shè)置:顯示后指針減一
if(c==0)//若結(jié)果為0
lcdwrd(0x30);//顯示0
while(c!=0)
{
lcdwrd(0x30+c%10);//從后向前顯示最后一位
c=c/10;//去掉最后一位后再循環(huán)顯示
}
lcdwrd(0x3d);//顯示=
}break;
/*******除法運算*********/
case 4: //除法運算
{
if(b==0)//若除數(shù)為0
{
lcdwrc(0x01);//清屏
for(j=0;j<11;j++)
{
lcdwrd(ERROR[j]);//顯示語句:ERROR!
}
delay(1000);//延時
lcdinit();//重新初始化LCD1602
}
else
{
c=(long)(((float)a/b)*10000);//將結(jié)果放大10000倍,即:若無法整除,保留4位小數(shù)
x=c;
lcdwrc(0x4f+0x80);//光標(biāo)置于第二行末尾
lcdwrc(0x04);//顯示設(shè)置:顯示后指針減一
while(c!=0)//一位一位顯示
{
k++;
lcdwrd(0x30+c%10);//顯示結(jié)果的最后一位在0x4f的位置 //0 00 000 0000
c=c/10;//取前面的結(jié)果數(shù)據(jù)
if(x>0&&x<=9)//0.0001到0.0009
{
if(k==1)//只有小數(shù)點后最后一位 x.000x
{
lcdwrd(0x30);//0
lcdwrd(0x30);//0
lcdwrd(0x30);//0
lcdwrd(0x2e);//.
k=0;
}
}
if(x>9&&x<=99)//0.0010到0.0099
{
if(k==2)//只有小數(shù)點后最后兩位 x.00xx
{
lcdwrd(0x30);//0
lcdwrd(0x30);//0
lcdwrd(0x2e);//.
k=0;
}
}
if(x>99&&x<=999)//0.0100到0.0999
{
if(k==3)//只有小數(shù)點后最后三位 x.0xxx
{
lcdwrd(0x30);//0
lcdwrd(0x2e);//.
k=0;
}
}
else if(k==4)//小數(shù)點后四位都非零 x.xxxx
{
lcdwrd(0x2e);//.
}
}
if(x<10000)//若結(jié)果小于1,在個位補0
lcdwrd(0x30);//個位補0
lcdwrd(0x3d);//顯示=
k=0;//將k定回0用于下次計算
}
} break;
}
}
}
while(P1!=0xf0);break;//當(dāng)有按鍵被按下時,結(jié)束此次判斷,進行下一次判斷
/********************第四列有按鍵按下*********************/
case 0x0e://0000 1110 第四列有按鍵被按下
{
fuhao=1;//有符號鍵被按下
P1=0xf0;//1111 0000
switch(P1)
{
case 0x70:/*0111 0000*/flag=4;lcdwrd(0xfd);break;//“/”第四列第一行
case 0xb0:/*1011 0000*/flag=3;lcdwrd(0x2a);break;//“*”第四列第二行
case 0xd0:/*1101 0000*/flag=2;lcdwrd(0x2d);break;//“-”第四列第三行
case 0xe0:/*1110 0000*/flag=1;lcdwrd(0x2b);break;//“+”第四列第四行
}
}
while(P1!=0xf0);break;
}
}
}
}
?
?
?
?
?
?
5 演示?
- 測試開機顯示歡迎語
- 測試計算模式選擇
- 測試加法運算功能
- 測試減法運算功能
- 測試乘法運算功能
- 測試除法運算功能
- 測試除數(shù)為0時顯示“ERROR!”
6 結(jié)論
? ? 制作過程中建議先學(xué)會使用單個模塊的功能,再將這些部分拼接起來,從而組成完整的計算器。
7 源代碼
#include <REGX51.H>
typedef unsigned int uint; //定于無符號int
typedef unsigned char uchar; //定義無符號char
/*****************************定義引腳**********************************/
sbit rw=P2^5;
sbit rs=P2^6;
sbit e=P2^7;
/*****************************定義變量**********************************/
uint fuhao,flag,k,i,j,num;
uchar ERROR[]=" ERROR!";//除數(shù)為0時,顯示
uchar wel[]=" Welcome!";//初始化時顯示
uchar MODE1[]=" MODE1";
long a,b,c,x;
/*****************************延時函數(shù)**********************************/
void delay(unsigned int xms)//延時x毫秒
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=112;j>0;j--);
return;
}
/*****************************LCD寫命令————位置**********************************/
void lcdwrc(uint c)
{
delay(100);
rs=0;
rw=0;
e=0;
P0=c;
e=1;
delay(100);
e=0;
}
/*****************************LCD寫數(shù)據(jù)————內(nèi)容**********************************/
void lcdwrd(uint dat) //設(shè)置LCD寫數(shù)據(jù)
{
delay(100);
rs=1;
rw=0;
e=0;
P0=dat;
e=1;
delay(100);
e=0;
rs=0;
}
/*****************************初始化LCD**********************************/
void lcdinit() //初始化LCD
{
delay(150);
lcdwrc(0x38);//寫指令38H
delay(50);
lcdwrc(0x38);//顯示模式設(shè)置
delay(50);
lcdwrc(0x38);
delay(50);
lcdwrc(0x38);//功能設(shè)定指令
lcdwrc(0x08);
lcdwrc(0x01);//清屏
lcdwrc(0x06);//顯示光標(biāo)移動設(shè)置
lcdwrc(0x0c); //顯示開關(guān)控制指令
num=0;//用于判定按鍵是否為“=”或者“歸零”時的變量
fuhao=0;//用于判定是否為運算符號
flag=0;//用于判定運算方式時的變量
a=0;//計算的第一個數(shù)
b=0;//計算的后一個數(shù)
c=0;//計算結(jié)果
x=0;//判定小數(shù)點的變量,暫存c值
k=0;//判定小數(shù)點的變量,小數(shù)點后非零數(shù)個數(shù)
j=0;//顯示ERROR時的循環(huán)用變量
}
/*****************************模式判定函數(shù)**********************************/
void MODE()
{
if(P2_0==0)
{
for(j=0;j<10;j++)
lcdwrd(MODE1[j]);//顯示語句:MODE1
delay(1000);//延時
lcdinit();//重新初始化LCD1602
}
}
/*****************************計算器函數(shù)**********************************/
void KeyDown()//計算器函數(shù)
{
k=0;
P1=0x0f; //0000 11111,行都為低電平0,列都為高電平
if(P1!=0x0f)//P1不為0x0f,則判定為有按鍵被按下
{
delay(100);//消抖
if(P1!=0x0f)//延時后,再次判斷
{
P1=0x0f;//0000 11111,行都為低電平0,列都為高電平
switch(P1)//
{
/********************第一列有按鍵按下*********************/
case 0x07://0000 0111 第一列有按鍵被按下
{
P1=0xf0;//列都為低電平0,行都為高電平1
switch(P1)//判斷哪一行的按鍵被按下
{
case 0x70: num = 1/*S1*/;k=7;break; //0111 0000第一列第一行 數(shù)字7
case 0xb0: num = 5/*S5*/;k=4;break; //1011 0000第一列第二行 數(shù)字4
case 0xd0: num = 9/*S9*/;k=1;break; //1101 0000第一列第三行 數(shù)字1
case 0xe0: num = 13/*S13*/;break; //1110 0000第一列第四行 歸零
}
if(num!=13)//被按下的按鍵不是歸零鍵
{
if(fuhao==0)//fuhao==0,表示第一個數(shù)a,fuhao==1,表示第二個數(shù)b
a=a*10+k;
else
b=b*10+k;
}
lcdwrd(0x30+k);//顯示按下的數(shù),0x30為ASCII碼中數(shù)字組的開頭,0x3k:顯示k,即按下數(shù)字k
if(num==13)//按下的按鍵是清零鍵
{
lcdwrc(0x01); //清屏指令
lcdinit();//重新初始化LCD1602
}
}while(P1!=0xf0);break;//當(dāng)有按鍵被按下時,結(jié)束此次判斷,進行下一次判斷
/********************第二列有按鍵按下*********************/
case 0x0b: //0000 1011 第二列有按鍵被按下
{
P1=0xf0;//行都為高電平1,列都為低電平0
switch(P1)//判斷哪一行有按鍵被按下
{
case 0x70: k=8;break;//第二列第一行 數(shù)字8
case 0xb0: k=5;break;//第二列第二行 數(shù)字5
case 0xd0: k=2;break;//第二列第三行 數(shù)字2
case 0xe0: k=0;break;//第二列第四行 數(shù)字0
}
if(fuhao==0)//fuhao==0,表示第一個數(shù)a,fuhao==1,表示第二個數(shù)b
a=a*10+k;
else
b=b*10+k;
lcdwrd(0x30+k);//顯示按下的數(shù),0x30為ASCII碼中數(shù)字組的開頭,0x3k:顯示k,即按下數(shù)字k
} while(P1!=0xf0);break;//當(dāng)有按鍵被按下時,結(jié)束此次判斷,進行下一次判斷
/********************第三列有按鍵按下*********************/
case 0x0d: //0000 1101 第三列有按鍵被按下
{
P1=0xf0;//行都為高電平1,列都為低電平0
switch(P1)//判斷哪一行有按鍵被按下
{
case 0x70: num=3;k=9;break;//第三列第一行 數(shù)字9
case 0xb0: num=7;k=6;break;//第三列第二行 數(shù)字6
case 0xd0: num=11;k=3;break;//第三列第三行 數(shù)字3
case 0xe0: num=15;break;//第三列第四行 “=”鍵
}
if(num!=15)//按下的鍵不為“=”鍵
{
if(fuhao==0)//fuhao==0,表示第一個數(shù)a,fuhao==1,表示第二個數(shù)b
a=a*10+k;
else
b=b*10+k;
lcdwrd(0x30+k);//顯示按下的數(shù),0x30為ASCII碼中數(shù)字組的開頭,0x3k:顯示k,即按下數(shù)字k
}
/************"="鍵被按下************/
if(num==15)//按下的鍵為=鍵
{
switch(flag)//判斷進行哪種運算
{
/*******加法運算*********/
case 1://加法運算
{
c=a+b;//計算結(jié)果
lcdwrc(0x4f/*第二行末尾位置*/+0x80);//光標(biāo)置于第二行末尾
lcdwrc(0x04);//設(shè)置顯示方式:顯示后指針減一,即前移一位
if(c==0)//若結(jié)果為0
lcdwrd(0x30);//顯示0
while(c!=0)
{
lcdwrd(0x30+c%10);//從后向前顯示最后一位
c=c/10;//去掉最后一位后再循環(huán)顯示
}
lcdwrd(0x3d);//顯示完計算結(jié)果后,顯示“=”
}break;
/*******減法運算*********/
case 2://減法運算
{
if(a>b)//大數(shù)減小數(shù)
c=a-b;
else//小數(shù)減大數(shù)
c=b-a;//計算兩數(shù)相減的絕對值
lcdwrc(0x4f+0x80);//將光標(biāo)置于第二行末尾
lcdwrc(0x04);//設(shè)置顯示方式:顯示后指針減一
if(c==0)//若結(jié)果為零
lcdwrd(0x30);//顯示0
while(c!=0)
{
lcdwrd(0x30+c%10);//從后向前顯示最后一位
c=c/10;//去掉最后一位后再循環(huán)顯示
}
if(a<b)//若結(jié)果為負(fù)數(shù)
lcdwrd(0x2d);//ASCII中的“-”,顯示負(fù)號
lcdwrd(0x3d);//顯示=
}break;
/*******乘法運算*********/
case 3://乘法運算
{
c=a*b; //計算結(jié)果
lcdwrc(0x4f+0x80);//光標(biāo)置于第二行末尾
lcdwrc(0x04);//顯示設(shè)置:顯示后指針減一
if(c==0)//若結(jié)果為0
lcdwrd(0x30);//顯示0
while(c!=0)
{
lcdwrd(0x30+c%10);//從后向前顯示最后一位
c=c/10;//去掉最后一位后再循環(huán)顯示
}
lcdwrd(0x3d);//顯示=
}break;
/*******除法運算*********/
case 4: //除法運算
{
if(b==0)//若除數(shù)為0
{
lcdwrc(0x01);//清屏
for(j=0;j<11;j++)
{
lcdwrd(ERROR[j]);//顯示語句:ERROR!
}
delay(1000);//延時
lcdinit();//重新初始化LCD1602
}
else
{
c=(long)(((float)a/b)*10000);//將結(jié)果放大10000倍,即:若無法整除,保留4位小數(shù)
x=c;
lcdwrc(0x4f+0x80);//光標(biāo)置于第二行末尾
lcdwrc(0x04);//顯示設(shè)置:顯示后指針減一
while(c!=0)//一位一位顯示
{
k++;
lcdwrd(0x30+c%10);//顯示結(jié)果的最后一位在0x4f的位置 //0 00 000 0000
c=c/10;//取前面的結(jié)果數(shù)據(jù)
if(x>0&&x<=9)//0.0001到0.0009
{
if(k==1)//只有小數(shù)點后最后一位 x.000x
{
lcdwrd(0x30);//0
lcdwrd(0x30);//0
lcdwrd(0x30);//0
lcdwrd(0x2e);//.
k=0;
}
}
if(x>9&&x<=99)//0.0010到0.0099
{
if(k==2)//只有小數(shù)點后最后兩位 x.00xx
{
lcdwrd(0x30);//0
lcdwrd(0x30);//0
lcdwrd(0x2e);//.
k=0;
}
}
if(x>99&&x<=999)//0.0100到0.0999
{
if(k==3)//只有小數(shù)點后最后三位 x.0xxx
{
lcdwrd(0x30);//0
lcdwrd(0x2e);//.
k=0;
}
}
else if(k==4)//小數(shù)點后四位都非零 x.xxxx
{
lcdwrd(0x2e);//.
}
}
if(x<10000)//若結(jié)果小于1,在個位補0
lcdwrd(0x30);//個位補0
lcdwrd(0x3d);//顯示=
k=0;//將k定回0用于下次計算
}
} break;
}
}
}
while(P1!=0xf0);break;//當(dāng)有按鍵被按下時,結(jié)束此次判斷,進行下一次判斷
/********************第四列有按鍵按下*********************/
case 0x0e://0000 1110 第四列有按鍵被按下
{
fuhao=1;//有符號鍵被按下
P1=0xf0;//1111 0000
switch(P1)
{
case 0x70:/*0111 0000*/flag=4;lcdwrd(0xfd);break;//“/”第四列第一行
case 0xb0:/*1011 0000*/flag=3;lcdwrd(0x2a);break;//“*”第四列第二行
case 0xd0:/*1101 0000*/flag=2;lcdwrd(0x2d);break;//“-”第四列第三行
case 0xe0:/*1110 0000*/flag=1;lcdwrd(0x2b);break;//“+”第四列第四行
}
}
while(P1!=0xf0);break;
}
}
}
}
/*****************************主函數(shù)**********************************/
void main()
{
uint x;
lcdinit();//LCD1602初始化
for(x=0;x<12;x++)
lcdwrd(wel[x]);//顯示歡迎語句:Welcome
delay(1000);
lcdwrc(0x01);//LCd1602清屏
while(1)
{
MODE();//功能判定函數(shù)
KeyDown();//按鍵判斷函數(shù)
}
}
?
?
?
到了這里,關(guān)于【附報告】51單片機計算器(LCD1602液晶顯示)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!