欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標(biāo)題:
單片機實現(xiàn)4*4矩陣式鍵盤計算器源程序+Proteus仿真
[打印本頁]
作者:
150hailong
時間:
2019-7-10 09:07
標(biāo)題:
單片機實現(xiàn)4*4矩陣式鍵盤計算器源程序+Proteus仿真
以AT89C51單片機為核心實現(xiàn)一個4*4矩陣式鍵盤計算器,該計算器可以實現(xiàn)基本加減乘除功能,并且用LCD顯示鍵盤輸入數(shù)和運算符號。
計算器仿真圖.png
(62.96 KB, 下載次數(shù): 42)
下載附件
2019-7-10 09:03 上傳
單片機源程序如下:
#include<reg51.h>
#include<stdio.h>
#include<stdlib.h>
unsigned char n;
float idata a,b; //兩個操作數(shù)
void key_scan(void); //鍵盤掃描
void init(); //LCD初始化
void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s);//字符串顯示
void LCD_dsp_char( unsigned x,unsigned char y,unsigned char dat); //字符顯示
void write_com(unsigned char com);
sbit lcden=P2^7; //讀寫控制輸入端
sbit rw=P2^6; //讀寫控制端
sbit rs=P2^5; //指令與數(shù)據(jù)選擇
sbit busy=P0^7; //LCD忙碌標(biāo)識
void delay(unsigned int i) //延時程序
{
unsigned int n;
for(n=0;n<=i;n++);
}
void main()
{
char idata temp[16]; //臨時存儲區(qū)
char i=0,j=0,fuhao; //i,j分別為temp與LCD的數(shù)據(jù)指針
bit flag=0,dh=0,fh=0,xsd=0;
//flag=0:操作數(shù)1,flag=1:操作數(shù)2;dh=1時表示已輸入等號;fh負(fù)號;xsd小數(shù)點
init(); //小數(shù)點
LCD_dsp_string(4,0,"Welcome!");
do
{
key_scan();
} while(n==17); //等待按鍵
write_com(0x01); //清屏
while(1)
{
key_scan(); //等待按鍵
if((dh==1)&(flag==1)&(n!=17)) //一次計算完畢后執(zhí)行
{
write_com(0x01); //清屏
LCD_dsp_string(0,0,temp); //輸出上次計算的結(jié)果
j=0;
i=0;
flag=0;
fh=0;
while(temp[i++]!='\0') j++;
//將temp數(shù)據(jù)指針移向后一個空位,將LCD顯示指針移向下一個空位
}
if((i==0)&(n=='-')&(fh==0)) //如果輸入的第一個數(shù)是負(fù)數(shù)則執(zhí)行
{
fh=1; //表示有負(fù)號
temp[0]='-'; //保存負(fù)號
i++;
LCD_dsp_char(j++,0,n); //輸出減號
if(flag==0) continue;
}
if(((n>='0')&(n<='9')|((n=='c')&(xsd==0)))&(dh==0))
{
if(n=='c')
{
n='.';
xsd=1; //防止再次按下c后繼續(xù)出現(xiàn)小數(shù)點
}
temp[i++]=n; //保存輸入的數(shù)字
LCD_dsp_char(j++,0,n); //顯示并將光標(biāo)移至下一位(光標(biāo)未顯示)
}
if(((n=='+')|(n=='-')|(n=='*')|(n=='/'))&((flag==0)|(dh==1)))
//輸入完第一個操作數(shù)之后或者完成一次計算之后按下運算符按鍵時執(zhí)行
{
flag=1; //之后輸入的操作數(shù)是第二個操作數(shù)
fuhao=n;
temp[i]='\0'; //表示為字符串
a=atof(temp); //轉(zhuǎn)換為數(shù)據(jù)
i=0;
dh=0;
xsd=0; //之后第二個操作數(shù)中可以添加一個小數(shù)點
switch(n)
{
case '+': LCD_dsp_char(j++,0,n); break;
case '-': LCD_dsp_char(j++,0,n);
fh=0; break;
case '*': LCD_dsp_char(j++,0,n); break;
case '/': LCD_dsp_char(j++,0,n); break;
} //顯示運算符
}
if((n=='=')&(flag==1)) //已輸入完第二個操作數(shù)并按下等號
{
dh=1;
temp[i]='\0';
b=atof(temp);
i=0;
xsd=0;
LCD_dsp_char(j,0,'='); //顯示等號
switch(fuhao)
{
case '+': a=a+b; break;
case '-': a=a-b; break;
case '*': a=a*b; break;
case '/': a=a/b; break;
} //計算
if(a>9999)
{
sprintf(temp,"%s","Error");
//若計算結(jié)果超過四位數(shù)則輸出錯誤信息
LCD_dsp_string(0,1,temp);
n=17;
do
{
key_scan();
}while(n==17); //等待按鍵
write_com(0x01); //清屏
a=b=0;
fuhao=0;
flag=0;
i=0;
j=0;
dh=0;
xsd=0;
fh=0; //恢復(fù)初始化
}
else
{
sprintf(temp,"%g",a); //輸出計算結(jié)果
LCD_dsp_string(0,1,temp);
}
}
if(n=='c') //按下清除鍵
{
write_com(0x01); //清屏
a=b=0;
fuhao=0;
flag=0;
i=0;
j=0;
dh=0;
xsd=0;
fh=0; //恢復(fù)初始化
}
}
}
void key_scan(void)
{
unsigned char temp;
P1=0xfe;
if(P1!=0xfe)
{
delay(200);
if(P1!=0xfe)
{
temp=P1&0xf0;
switch(temp)
{
case 0xe0:n='c';break;
case 0xd0:n='0';break;
case 0xb0:n='=';break;
case 0x70:n='+';break;
}
}
while(P1!=0xfe);
}
else
{
P1=0xfd;
if(P1!=0xfd)
{
delay(200);
if(P1!=0xfd)
{
temp=P1&0xf0;
switch(temp)
{
case 0xe0:n='1';break;
case 0xd0:n='2';break;
case 0xb0:n='3';break;
case 0x70:n='-';break;
}
}
while(P1!=0xfd);
}
else{
P1=0xfb;
if(P1!=0xfb)
{
delay(200);
if(P1!=0xfb)
{
temp=P1&0xf0;
switch(temp)
{
case 0xe0:n='4';break;
case 0xd0:n='5';break;
case 0xb0:n='6';break;
case 0x70:n='*';break;
}
}
while(P1!=0xfb);
}
else{
P1=0xf7;
if(P1!=0xf7)
{
delay(200);
if(P1!=0xf7)
{
temp=P1&0xf0;
switch(temp)
{
case 0xe0:n='7';break;
case 0xd0:n='8';break;
case 0xb0:n='9';break;
case 0x70:n='/';break;
}
}
while(P1!=0xf7);
}
else n=17;
}}}
}
void check() //判斷LCD是否忙碌
{
do
{
P0=0xff;
rs=0;
rw=1;
lcden=0;
delay(100);
lcden=1;
}while(busy==1); //當(dāng)busy=1,即LCD忙時,等待
}
void write_com(unsigned char com) //寫顯示命令
{
P0=com;
rs=0;
rw=0;
lcden=0;
check();
lcden=1;
}
void write_data(unsigned char date) //寫顯示數(shù)據(jù)
{
P0=date;
rs=1;
rw=0;
lcden=0;
check();
lcden=1;
}
void init() //初始化LCD
{
write_com(0x38); //16x2行顯示,5x7點陣,8位數(shù)據(jù)接口
write_com(0x0c); //開顯示,光標(biāo)不顯示、不閃爍
write_com(0x06); //光標(biāo)自增,畫面不動
write_com(0x80); //選擇第一行
write_com(0x01); //清屏
}
void LCD_set_xy( unsigned char x, unsigned char y )//設(shè)置LCD顯示的位置
{
unsigned char address;
if (y == 0) //y=0為第一行
address = 0x80 + x; //x=0為一行的第一個
else //第二行
address =0xc0+ x;
write_com(address); //設(shè)置數(shù)據(jù)指針位置
}
void LCD_dsp_char( unsigned x,unsigned char y,unsigned char dat)
//單個字符顯示函數(shù)
{
LCD_set_xy( x, y ); //設(shè)置顯示位置
write_data(dat); //寫入待顯示數(shù)據(jù)
}
void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s)
//字符串顯示函數(shù)
{
LCD_set_xy( X, Y );
while (*s) //當(dāng)字符串未到達結(jié)尾('\0')時,循環(huán)輸出單個字符
{
write_data(*s);
s ++; //指向下一個字符
}
}
復(fù)制代碼
所有資料51hei提供下載:
計算器.zip
(1.24 MB, 下載次數(shù): 65)
2019-7-10 09:04 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
1440800408
時間:
2019-12-7 09:38
請問還能實現(xiàn)十進制和二進制互相轉(zhuǎn)換嗎
作者:
無名撒旦
時間:
2020-1-10 13:52
開關(guān)都沒有實現(xiàn)!坑比!大家別下載!
作者:
sunnywe
時間:
2020-5-9 22:26
挺好的,有參考價值 想問問樓主他的工作原理是是嗎
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1