欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
簡易計算器的設計及實現加(減)功能
[打印本頁]
作者:
xhyan520
時間:
2018-6-19 17:53
標題:
簡易計算器的設計及實現加(減)功能
用Proteus實現
計算器功能的實現:實現加(減)功能。
單片機源程序如下:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P0^0;
sbit rw=P0^1;
sbit e=P0^2;
sbit k0=P1^0;
sbit k1=P1^1;
sbit k2=P1^2;
sbit k3=P1^3;
sbit k4=P1^4;
sbit k5=P1^5;
sbit k6=P1^6;
sbit k7=P1^7;
unsigned char code digit[ ]={"0123456789"}; //定義字符數組顯示數字
unsigned char s,m,h,day,month,year,count;
void write_dat(uchar dat);
void write_com(uchar com);
void keyscan();
/**********************
功能說明:
顯示編碼,加上0x30,
分別為'1','2','3','+',
'4','5','6','-',等
**********************/
uchar code table1[]=
{
1,2,3,0x2b-0x30,
4,5,6,0x2d-0x30,
7,8,9,0x2a-0x30,
0,0x3d-0x30,0x01-0x30,0x2f-0x30
};
uchar k=0,flag=0,num,fuhao,i;
long a,b,c;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*****************************************************
函數功能:指定字符顯示的實際地址
入口參數:x
***************************************************/
void WriteAddress(unsigned char x)
{
write_com(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"
}
/******************************************************************************
函數功能:顯示小時
******************************************************************************/
void DisplayHour()
{
unsigned char i,j;
i=h/10; //取整運算,求得十位數字
j=h%10; //取余運算,求得各位數字
WriteAddress(0x45); //寫顯示地址,將十位數字顯示在第2行第0列
write_dat(digit[i]); //將十位數字的字符常量寫入LCD
write_dat(digit[j]); //將個位數字的字符常量寫入LCD
}
/******************************************************************************
函數功能:顯示分鐘
******************************************************************************/
void DisplayMinute()
{
unsigned char i,j;
i=m/10; //取整運算,求得十位數字
j=m%10; //取余運算,求得各位數字
WriteAddress(0x48); //寫顯示地址,將十位數字顯示在第2行第3列
write_dat(digit[i]); //將十位數字的字符常量寫入LCD
write_dat(digit[j]); //將個位數字的字符常量寫入LCD
}
/******************************************************************************
函數功能:顯示秒
******************************************************************************/
void DisplaySecond()
{
unsigned char i,j;
i=s/10; //取整運算,求得十位數字
j=s%10; //取余運算,求得各位數字
WriteAddress(0x4b); //寫顯示地址,將十位數字顯示在第2行第6列
write_dat(digit[i]); //將十位數字的字符常量寫入LCD
write_dat(digit[j]); //將個位數字的字符常量寫入LCD
}
/******************************************************************************
函數功能:顯示小時
******************************************************************************/
void DisplayYear()
{
unsigned char i,j;
i=year/10; //取整運算,求得十位數字
j=year%10; //取余運算,求得各位數字
WriteAddress(0x07); //寫顯示地址,將十位數字顯示在第2行第0列
write_dat(digit[i]); //將十位數字的字符常量寫入LCD
write_dat(digit[j]); //將個位數字的字符常量寫入LCD
}
/******************************************************************************
函數功能:顯示分鐘
******************************************************************************/
void DisplayMonth()
{
unsigned char i,j;
i=month/10; //取整運算,求得十位數字
j=month%10; //取余運算,求得各位數字
WriteAddress(0x0a); //寫顯示地址,將十位數字顯示在第2行第3列
write_dat(digit[i]); //將十位數字的字符常量寫入LCD
write_dat(digit[j]); //將個位數字的字符常量寫入LCD
}
/******************************************************************************
函數功能:顯示秒
******************************************************************************/
void DisplayDay()
{
unsigned char i,j;
i=day/10; //取整運算,求得十位數字
j=day%10; //取余運算,求得各位數字
WriteAddress(0x0d); //寫顯示地址,將十位數字顯示在第2行第6列
write_dat(digit[i]); //將十位數字的字符常量寫入LCD
write_dat(digit[j]); //將個位數字的字符常量寫入LCD
}
void keyscan2()
{if(k0==0)
{delay(5);
if(k0==0)
{
s++;
if(s==60)
s=0;
}
}
if(k1==0)
{delay(5);
if(k1==0)
{m++;
if(m==60)
m=0;
}
}
if(k2==0)
{delay(5);
if(k2==0)
{h++;
if(h==60)
h=0;
}
}
if(k3==0)
{delay(5);
if(k3==0)
{day++;
if(day==30)
day=0;
}
}
if(k4==0)
{delay(5);
if(k4==0)
{month++;
if(month==13)
month=0;
}
}
if(k5==0)
{delay(5);
if(k5==0)
{year++;
if(year==99)
year=0;
}
}
}
void keyscan()
{
uchar temp;
P3=0xfe;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:num=0;
break;
case 0xde:num=1;
break;
case 0xbe:num=2;
break;
case 0x7e:num=3;
break;
}
while(temp!=0xf0)
{ temp=P3;
temp=temp&0xf0;
}
}
/*當按下1,2,3,松手后執行下面這段語句*/
if(num==0||num==1||num==2)
{
if(flag==0)
a=a*10+table1[num];//如果沒有按符號鍵,符號前的數值為a
else if(flag==1)
b=b*10+table1[num]; //如果按了符號鍵,符號后的數值為b
if(k==1) //如果之前按了'='號,再按鍵時清屏,進行下一次計算
{
k=0;
write_com(0x01);
}
}
else if(num==3) //判斷按下'+'
{
flag=1;
fuhao=1;
}
i=table1[num]; //顯示按下的鍵
write_dat(0x30+i);
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:num=4;
break;
case 0xdd:num=5;
break;
case 0xbd:num=6;
break;
case 0x7d:num=7;
break;
}
while(temp!=0xf0)
{ temp=P3;
temp=temp&0xf0;
}
}
if(num==4||num==5||num==6) //判斷是否按下'4','5','6'
{
if(k==1)
{
k=0;
write_com(0x01);
}
if(flag==0)
a=a*10+table1[num];
else if(flag==1)
b=b*10+table1[num];
}
else if(num==7)
{
flag=1;
fuhao=2;
}
i=table1[num]; //顯示按下的鍵
write_dat(0x30+i);
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp) //
{
case 0xeb:num=8;
break;
case 0xdb:num=9;
break;
case 0xbb:num=10;
break;
case 0x7b:num=11;
break;
}
while(temp!=0xf0)
{ temp=P3;
temp=temp&0xf0;
}
}
if(num==8||num==9||num==10) //判斷是否按下'7','8','9'
{
if(k==1)
{
k=0;
write_com(0x01);
}
if(flag==0)
a=a*10+table1[num];
else if(flag==1)
b=b*10+table1[num];
}
else if(num==11) //判斷是否按下'*'
{
flag=1;
fuhao=3;
}
i=table1[num];
write_dat(0x30+i);
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xe7:num=12; // 0鍵
break;
case 0xd7:num=13; // '='
break;
case 0xb7:num=14; //清零鍵
break;
case 0x77:num=15; //'/'
break;
}
while(temp!=0xf0)
{ temp=P3;
temp=temp&0xf0;
}
}
switch(num)
{
case 12:
{
if(k==1)
{
k=0;
write_com(0x01);
}
if(flag==0)
a=a*10;
else if(flag==1)
b=b*10;
write_dat(0x30);
}
break;
case 13: //按=鍵
{
k=1;
if(fuhao==1) //如果符號鍵是+,執行+運算
{
write_com(0x80+0x4f);
write_com(0x04);
c=a+b;
while(c!=0)
{
write_dat(0x30+c%10);
c=c/10;
}
write_dat(0x3d);
fuhao=0;
a=0;b=0;flag=0;
}
if(fuhao==2)
{
write_com(0x80+0x4f);
write_com(0x04);
if(a>=b)
{
c=a-b;
while(c!=0)
{
write_dat(0x30+c%10);
c=c/10;
}
}
else if(a<b)
{
c=b-a;
while(c!=0)
{
write_dat(0x30+c%10);
c=c/10;
}
write_dat(0x2d);
}
write_dat(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
if(fuhao==3) //如果符號鍵是*
{
write_com(0x80+0x4f);
write_com(0x04);
c=a*b;
while(c!=0)
{
write_dat(0x30+c%10);
c=c/10;
}
write_dat(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
if(fuhao==4) //如果符號鍵是/
{
i=0;
write_com(0x80+0x4f);
write_com(0x04);
c=(long)(((float)a/b)*1000000); //結果保留6位小數
while(c!=0)
{
write_dat(0x30+c%10);
c=c/10;
i++;
if(i==6) // 顯示完六位小數后,顯示·
write_dat(0x2e);
}
if(a/b<=0)
write_dat(0x30);
write_dat(0x3d);
a=0;b=0;flag=0;fuhao=0;
}
}
break;
case 14:
{ write_com(0x01);
a=0;b=0;flag=0;fuhao=0;
}
break;
case 15:
{
flag=1;
fuhao=4;
write_dat(0x30+table1[num]);
}
break;
}
}
}
/*******led1602*******/
void write_com(uchar com)
{
rs=0;//選擇寫指令
rw=0;
P2=com;
e=1;
delay(5);//無延時不能正常工作
e=0;
}
void write_dat(uchar dat)
{
rs=1;//選擇寫數據
rw=0;
P2=dat;
e=1;
delay(5);//無延時不能正常工作
e=0;
}
void init() //初始化
{
delay(15);
write_com(0x38);
delay(6);
write_com(0x38);
delay(6);
write_com(0x38);
write_com(0x38);
write_com(0x0c); //開顯示,關光標
write_com(0x06);//光標移動 設置
write_com(0x01);//清屏
}
void geshi()
{
WriteAddress(0x00);
write_dat('D');
WriteAddress(0x01);
write_dat('a');
WriteAddress(0x02);
write_dat('t'); //將分號的字符常量寫入LCD
WriteAddress(0x03);
write_dat('e');
WriteAddress(0x04);
write_dat(':');
WriteAddress(0x05);
write_dat('2');
WriteAddress(0x06);
write_dat('0');
WriteAddress(0x09);
write_dat('-');
WriteAddress(0x0c);
write_dat('-');
WriteAddress(0x40);
write_dat('T');
WriteAddress(0x41);
write_dat('i');
WriteAddress(0x42);
write_dat('m');
WriteAddress(0x43); //寫地址,將第二個分號顯示在第2行第7列
write_dat('e'); //將分號的字符常量寫入LCD
WriteAddress(0x44); //寫地址,將第二個分號顯示在第2行第10列
write_dat(':'); //將分號的字符常量寫入LCD
WriteAddress(0x47);
write_dat(':');
WriteAddress(0x4a);
write_dat(':');
}
void main()
{
init();
TMOD=0x01; //使用定時器T0的模式1
TH0=(65536-46083)/256; //定時器T0的高8位設置初值
TL0=(65536-46083)%256; //定時器T0的低8位設置初值
EA=1; //開總中斷
ET0=1; //定時器T0中斷允許
TR0=1; //啟動定時器T0
count=0; //中斷次數初始化為0
s=0; //秒初始化為0
m=0; //分鐘初始化為0
h=0; //小時初始化為0
year=0;
month=0;
day=0;
while(1)
{
keyscan();
if(k6==0)
{ k6=0;
write_com(0x01);
while(1)
{
keyscan2();
geshi();
delay(5);
DisplayHour();
delay(5);
DisplayMinute();
delay(5);
DisplaySecond();
delay(5);
DisplayYear();
delay(5);
DisplayMonth();
delay(5);
DisplayDay();
delay(5);
if(k7==0)
{
k6=1;
write_com(0x01);
break;
}
}
}
}
}
/*******************************************************
函數功能:定時器T0的中斷服務函數
********************************************************/
void Time0(void ) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第1組工作寄存器
{
count++; //每產生1次中斷,中斷累計次數加1
if(count==20) //如果中斷次數計滿20次
{
count=0; //中斷累計次數清0
s++; //秒加1
if(s==60) //如果計滿60秒
{
s=0; //秒清0
m++; //分鐘加1
}
if(m==60) //如果計滿60分
{
m=0; //分鐘清0
h++; //小時加1
}
if(h==24)
{
h=0;
day++;
}
if(day==30)
{
day=0;
month++;
}
if(month==13)
{ month=0;
year++;
}
if(year==99)
{
year=0;
}
TH0=(65536-46083)/256; //定時器T0高8位重新賦初值
TL0=(65536-46083)%256; //定時器T0低8位重新賦初值
}
}
復制代碼
所有資料51hei提供下載:
計算器.rar
(3.28 KB, 下載次數: 13)
2018-6-19 17:52 上傳
點擊文件名下載附件
簡易計算器的設計及實現
下載積分: 黑幣 -5
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1