1.設(shè)計任務(wù)
利用AT89C51單片機(jī)為核心控制元件,設(shè)計一個四位加法計算器,設(shè)計的系統(tǒng)實用性強(qiáng)、操作簡單,實現(xiàn)了智能化、數(shù)字化。
1)、通過4*4矩陣鍵盤輸入數(shù)字及運算符;
2)、可以進(jìn)行4位十進(jìn)制數(shù)以內(nèi)的加法運算。如果計算結(jié)果超出四位數(shù),則全部顯示“E ”LED燈亮起;
3)、可以進(jìn)行加減所有運算;
4)、添加其他功能。
2. 設(shè)計要求
2.1系統(tǒng)方案論證
根據(jù)設(shè)計任務(wù),分析設(shè)計系統(tǒng)的組成,給出實現(xiàn)設(shè)計任務(wù)的幾種方案,分析比較幾種設(shè)計方案的優(yōu)略,本著盡量以軟件代替硬件,同時力求電路簡單,工作可靠的原則,確定總體設(shè)計方案。
2.2系統(tǒng)硬件電路設(shè)計
根據(jù)系統(tǒng)設(shè)計方案進(jìn)行軟、硬件的分配,軟、硬件設(shè)計分別進(jìn)行。硬件設(shè)計包括單片機(jī)最小系統(tǒng)和擴(kuò)展接口及配置,硬件結(jié)構(gòu)在設(shè)計時要選擇合適的元器件,硬件電路要簡潔、工作可靠,需用Proteus繪制整個系統(tǒng)的電路仿真原理圖。
2.3軟件設(shè)計
根據(jù)該系統(tǒng)要求的功能進(jìn)行軟件設(shè)計,簡述軟件的功能,并根據(jù)每個模塊的功能繪制軟件流程圖,根據(jù)流程圖編寫程序并匯編調(diào)試通過;列出軟件清單,軟件清單要求加以注釋。
2.4 軟硬件系統(tǒng)仿真
將編譯后的程序軟件加載到Proteus軟件仿真的單片機(jī)ROM中,運行系統(tǒng),實現(xiàn)軟件程序?qū)纹瑱C(jī)系統(tǒng)的硬件電路的控制,并調(diào)試仿真結(jié)果,直至與設(shè)計任務(wù)相符。
#include <reg51.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
sbit rw=P2^5;
sbit rs=P2^6;
sbit e=P2^7;
sbit led=P2^0;
sbit beep=P2^1;
unsigned char key,num,ei,eii,p;
unsigned char dat1[]={1,2,3,0x2b-0x30, 4,5,6,0x2d-0x30, 7,8,9,0x2a-0x30,
0,0x01-0x30,0x3d-0x30,0x2b-0x30 };//保存顯示的數(shù)據(jù)
unsigned char dat2[]="9999 revo rewsna";
unsigned char dat3[]="Hi welcome into";
unsigned char dat4[]="counter by yumo";
void delay(unsigned int i);
void lcdwrc(unsigned char c);//寫入命令
void lcdwrd(unsigned char dat);//寫入數(shù)據(jù)
void lcdinit();//LCD初始化
show();
void keyscan();
void do_beep();
void do_led(int x);
void main()
{
led=0;
lcdinit();
show();//個性化界面
while(1)
{
keyscan();
}
}
void delay(unsigned int i)
{
while(i--);
}
void lcdwrc(unsigned char c)//寫入命令
{
delay(1000);
rs=0;//選擇發(fā)送命令
rw=0;//選擇寫入
e=0;//使能
P0=c;//放入命令
e=1;//寫時序
delay(1000);//保持時間
e=0;
}
void lcdwrd(unsigned char dat)//寫入數(shù)據(jù)
{
delay(1000);
rs=1;//選擇輸入數(shù)據(jù)
rw=0;//選擇寫入
e=0;
P0=dat;//寫入數(shù)據(jù)
e=1;//寫入時序
delay(1000);
e=0;
rs=0;
}
void lcdinit()//LCD初始化
{
delay(1500);
lcdwrc(0x38);
delay(500);
lcdwrc(0x38);
delay(500);
lcdwrc(0x38);
delay(500);
lcdwrc(0x38);
lcdwrc(0x08);
lcdwrc(0x01);
lcdwrc(0x06);
lcdwrc(0x0c);
key=0;
num=0;
flag=0;
fuhao=0;
a=0;
b=0;
c=0;
d=0;
}
show()
{
for(eii=0;eii<15;eii++)
{
lcdwrd(dat3[eii]);
}
lcdwrc(0xc0);//寫命令函數(shù)使其到第二行第一個字符
for(p=0;p<15;p++)
{
lcdwrd(dat4[p]);
}
return 1;
}
void keyscan()
{
P1=0xfe; //令第一行為0,然后判斷是哪一列按下
if(P1!=0xfe)
{
delay(1000);
if(P1!=0xfe)
{
key=P1&0xf0;
switch(key)
{
case 0xe0: num=0;break; //1
case 0xd0: num=1;break; //2
case 0xb0: num=2;break; //3
case 0x70: num=3;break; //加
}
}
while(P1!=0xfe);
if(num==0||num==1||num==2) //確認(rèn)第一行的數(shù)1,2,3
{
if(flag==0) //沒有按下符號鍵
{
a=a*10+dat1[num];
do_led(a);
}
else
{
delay(1000);
b=b*10+dat1[num];
do_led(b);
}
}
if(num==3)
{
flag=1;
fuhao=1;//加號+ 運行
}
lcdwrd(0x30+dat1[num]);
}
P1=0xfd; //令第二行為0,判斷是哪一列按下
if(P1!=0xfd)
{
delay(1000);
if(P1!=0xfd)
{
key=P1&0xf0;
switch(key)
{
case 0xe0: num=4;break; //4
case 0xd0: num=5;break; //5
case 0xb0: num=6;break; //6
case 0x70: num=7;break; //違規(guī)
}
}
while(P1!=0xfd);
if(num==4||num==5||num==6)
{
if(flag==0) //沒有按下符號鍵
{
a=a*10+dat1[num];
do_led(a);
}
else
{
b=b*10+dat1[num];
do_led(b);
}
}
if(num==7)
{
flag=1;
do_beep();
}
lcdwrd(0x30+dat1[num]);
}
P1=0xfb; //令第三行為0,判斷哪一列按下
if(P1!=0xfb)
{
delay(1000);
if(P1!=0xfb)
{
key=P1&0xf0;
switch(key)
{
case 0xe0: num=8;break; //7
case 0xd0: num=9;break; //8
case 0xb0: num=10;break; //9
case 0x70: num=11;break; //違規(guī)
}
}
while(P1!=0xfb);
if(num==8||num==9||num==10)
{
if(flag==0) //沒有按下符號鍵
{
a=a*10+dat1[num];
do_led(a);
}
else
{
b=b*10+dat1[num];
do_led(b);
}
}
else if(num==11)
{
flag=1;
do_beep();
}
lcdwrd(0x30+dat1[num]);
}
P1=0xf7; //令第四行為0,判斷哪一列按下
if(P1!=0xf7)
{
delay(1000);
if(P1!=0xf7)
{
key=P1&0xf0;
switch(key)
{
case 0xe0: num=12;break; //0
case 0xd0: num=13;break; //清除rst
case 0xb0: num=14;break; //等號=
case 0x70: num=15;break; //違規(guī)
}
}
while(P1!=0xf7);
switch(num)
{
case 12:
if(flag==0) //沒有按下符號鍵
{
a=a*10+dat1[num];
do_led(a);
lcdwrd(0x30);
}
else
{
b=b*10+dat1[num];
do_led(b);
lcdwrd(0x30);
}
break;
case 13:
lcdwrc(0x01); //清屏指令
a=0;
b=0;
c=0;
flag=0;
fuhao=0;
break;
case 15:
flag=1;
do_beep();
break;
case 14: //如果是等于號
if(fuhao==1)//加
{
lcdwrc(0x4f+0x80);
lcdwrc(0x04);//設(shè)置光標(biāo)左移,屏幕不移動
c=a+b;
if(c==0)
{
lcdwrc(0x4f+0x80);
lcdwrc(0x04);
lcdwrd(0x30);
}
while((c!=0)&&(c<=9999)) //一位一位顯示
{
lcdwrd(0x30+c%10);//顯示結(jié)果的最后一位在0x4f的位置
c=c/10;//取前面的結(jié)果數(shù)據(jù)
}
if(c>9999)
{
for(ei=0;ei<=16;ei++)
{
lcdwrd(dat2[ei]);
}
}
lcdwrd(0x3d); //顯示等于號=
a=0;
b=0;
c=0;
flag=0;
fuhao=0;//全部清除為0
}
break;
}
}
}
void do_beep()
{
beep = 0; //蜂鳴器報警
delay(100000);
beep = 1;
}
void do_led(int x)
{
if(x>9999)
{
led=1;
}
}
完整代碼點開鏈接私信獲取。文章來源:http://www.zghlxwxcb.cn/news/detail-761402.html
【iBot機(jī)器人工作室的個人空間-嗶哩嗶哩】 https://b23.tv/ryUWVKa文章來源地址http://www.zghlxwxcb.cn/news/detail-761402.html
到了這里,關(guān)于基于AT89C51單片機(jī)四位加法計算器的設(shè)計的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!