Altium Designer畫的單片機計算器原理圖和PCB圖如下:(51hei附件中可下載工程文件)
0.png (29.63 KB, 下載次數: 42)
下載附件
2019-3-24 04:06 上傳
3.png (88.94 KB, 下載次數: 37)
下載附件
2019-3-20 19:12 上傳
0.png (12.03 KB, 下載次數: 38)
下載附件
2019-3-24 04:06 上傳
計算器仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (15.37 KB, 下載次數: 40)
下載附件
2019-3-24 04:08 上傳
單片機源程序如下:
- #include<reg52.h>
- #include<math.h>
- #define unchar unsigned char
- #define unint unsigned int
- #define Pi 3.141596
- sbit rs=P2^0;
- sbit rw=P2^1;
- sbit en=P2^2;
- sbit busy=P0^7;
- char i,j,flag,fuhao,y,r,z;
- char s[30];
- unchar num,temp;
- long a,b,c;
- unchar code table[]={7,8,9,0,//內部運算用
- 4,5,6,0,
- 1,2,3,0,
- 0,0,0,0,
- 0,0,0,0,
- 0,0,0,0,
- 0,0,0,0};
- unchar code table1[]={7,8,9,0x2f-0x30,//顯示用7,8,9,/,//后面加了0x30,所以這里減掉
- 4,5,6,0x2a-0x30,//4,5,6,*
- 1,2,3,0x2d-0x30,//1,2,3,-
- 0x01-0x30,0,0x3d-0x30,0x2b-0x30,//ON/C,0,=,+
- 0x22-0x30,0x5e-0x30,0x25-0x30,0x21-0x30,//"代表根號,^次方,%,!
- 0x02-0x30,0x03-0x30,0x04-0x30,//2轉10,10轉2,10轉16,16轉10
- 0x05-0x30,0x06-0x30,0x07-0x30,0x08-0x30};//sin,coa,tan,ln
-
- void delay(unchar z)
- {
- unchar x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void checkbusy()
- {
- while(busy==1)//P0^7最高位為1為忙,0為閑
- {
- P0=0xff;
- rs=0;
- rw=1;
- en=0;//禁止讀寫
- delay(20);
- en=1;
- }
- }
- void write_com(unchar com)
- {
- rs=0;
- rw=0;
- en=0;
- checkbusy();
- P0=com;
- delay(5);
- en=1;
- delay(5);
- en=0;
- }
- void write_date(unchar date)
- {
- rs=1;
- rw=0;
- en=0;
- checkbusy();
- P0=date;
- delay(5);
- en=1;
- delay(5);
- en=0;
- }
- void init()
- {
- write_com(0x38);//16*2顯示,5*7點陣,8位數據接口
- delay(50);
- write_com(0x0c);//開顯示關光標和閃爍
- delay(50);
- write_com(0x06);//地址向后移
- delay(50);
- write_com(0x80);//光標初始地址
- write_com(0x01);//清屏
- delay(50);
- i=0;flag=0;//賦初值flag表示按符號鍵后的輸入值,默認為沒按之前的輸入
- fuhao=0;a=0;b=0;c=0;
-
-
- }
- void lcd_clean()//清屏
- {
- write_com(0x01);
- delay(20);
- }
- void keyscan()
- {
- //**************P3口的鍵盤檢測
- P3=0xfe;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delay(10);
- temp=P3;
- temp=temp&0xf0;
- if(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(P3!=0xfe);
- if(num==0||num==1||num==2)
- {
- if(flag==0)
- a=a*10+table[num];//a是在沒按符號鍵之前輸入的值
- if(flag==1)
- b=b*10+table[num];//b是按符號鍵后輸入的值
- }
- if(num==3)//"/"除鍵
- {
- flag=1;
- fuhao=4;//"/"
- }
- i=table1[num];//顯示的值
- write_date(0x30+i);//十六進制表示的ASC碼
- }
- P3=0xfd;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delay(5);
- temp=P3;
- temp=temp&0xf0;
- if(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(P3!=0xfd);
- if(num==4||num==5||num==6)
- {
- if(flag==0)
- a=a*10+table[num];
- else
- b=b*10+table[num];
- }
- if(num==7)//"*"乘
- {
- flag=1;
- fuhao=3;
- }
- i=table1[num];
- write_date(0x30+i);
- }
- P3=0xfb;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delay(5);
- temp=P3;
- temp=temp&0xf0;
- if(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(P3!=0xfb);
- if(num==8||num==9||num==10)
- {
- if(flag==0)
- {a=a*10+table[num];}
- else
- {b=b*10+table[num];}
- }
- if(num==11)//"-"減
- {
- flag=1;
- fuhao=2;
- }
-
- i=table1[num];
- write_date(0x30+i);
- }
- P3=0xf7;
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delay(5);
- temp=P3;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P3;
- switch(temp)
- {
- case 0xe7:num=12; break;
- case 0xd7:num=13; break;
- case 0xb7:num=14; break;
- case 0x77:num=15; break;
-
- }
- }
- while(P3!=0xf7);//松手檢測,沒有松手則保持顯示的狀態
- switch(num)
- {
- case 12:{
- lcd_clean();
- a=0;b=0;flag=0;
- fuhao=0;
- } break;
- case 13:{
- if(flag==0)
- {
- a=a*10;write_date(0x30);
- }
- else
- {
- b=b*10;
- write_date(0x30);
- }
- } break;
- case 14:{//需要按"="的
- if(fuhao==1)
- {
- write_com(0x80+0x0f);
- lcd_clean();//重新定位后再清屏
- write_com(0x04); i=0;
- c=a+b;
- while(c!=0)
- {
- write_date(0x30+c%10);
- c=c/10;
- }
- write_date(0x3d);//寫"="
- a=0;b=0;flag=0;fuhao=0;//清0
- }
- else if(fuhao==2)
- {
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- if(a-b>0)
- c=a-b;
- else
- c=b-a;
- while(c!=0)
- {
- write_date(0x30+c%10);
- c=c/10;
- }
- if(a-b<0)
- write_date(0x2d);//"-"減
- write_date(0x3d);
- a=0;b=0;flag=0;fuhao=0;
- }
- else if(fuhao==3)
- {
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- c=a*b;
- while(c!=0)
- {
- write_date(0x30+c%10);
- c=c/10;
- }
- write_date(0x3d);
- a=0;b=0;flag=0;fuhao=0;
- }
- else if(fuhao==4)
- {
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- i=0;
- c=(long)(((float)a/b)*1000);//化整后再加小數點
- while(c!=0)
- {
- write_date(0x30+c%10);
- c=c/10; i++;
- if(i==3)
- write_date(0x2e);//加小數點"."
- }
- if(a/b<=0)
- write_date(0x30);
- write_date(0x3d);
- a=0;b=0;flag=0;fuhao=0;
- }
- else if(fuhao==5)
- {
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- c=(long)(pow((float)a,(float)1/b)*1000);
- i=0;
- while(c!=0)
- {
- write_date(0x30+c%10);
- c=c/10;
- i++;
- if(i==3)
- write_date(0x2e);
- }
- write_date(0x3d);
- a=0;b=0;flag=0;fuhao=0;
- }
- else if(fuhao==6)
- {
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- c=pow((float)a,(float)b);//c52內部的函數
- while(c!=0)
- {
- write_date(0x30+c%10);
- c=c/10;
- }
- write_date(0x3d);
- a=0;b=0;flag=0;fuhao=0;
- }
- else if(fuhao==7)
- {
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- c=a%b;
- if(c==0)
- write_date(0x30);
- while(c>0)
- {
- write_date(0x30+c%10);
- c=c/10;
- }
- write_date(0x3d);
- a=0;b=0;flag=0;fuhao=0;
- }
-
- } break;
- case 15:{
- i=table1[num];
- write_date(0x30+i);//"+"加
- flag=1;fuhao=1;
- } break;
-
-
- }
- }
- //*********************P1口的鍵盤檢測
- P1=0xfe;
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delay(5);
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xee:num=16; break;
- case 0xde:num=17; break;
- case 0xbe:num=18; break;
- case 0x7e:num=19; break;
- }
- }
- while(P1!=0xfe);
- switch(num)
- {
- case 16:{
- i=table1[num];
- write_date(0x30+i);//"x開y次方
- flag=1;fuhao=5;
- } break;
- case 17:{
- i=table1[num];
- write_date(0x30+i);//"^"x的y次方
- flag=1;fuhao=6;
- } break;
- case 18:{
- i=table1[num];
- write_date(0x30+i);//"%"求余
- flag=1;fuhao=7;
- } break;
- case 19:{//單獨出來不用按"="號得結果
- unsigned long int c_1;
- i=table1[num];
- write_date(0x30+i);
- fuhao=8;//"!"階乘
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- c_1=1;
- for(i=1;i<=a;i++)//a的最大值為12,13時已經超出了無符號長整型的范圍無法計算
- c_1=c_1*i;
- while(c_1!=0)
- {
- write_date(0x30+c_1%10);
- c_1=c_1/10;
- }
- write_date(0x3d);
- a=0;fuhao=0;
- } break;
- }
- }
- P1=0xfd;
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delay(5);
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xed:num=20; break;
- case 0xdd:num=21; break;
- case 0xbd:num=22; break;
- case 0x7d:num=23; break;
- }
- }
- while(P1!=0xfd);
- switch(num)
- {
- case 20:{
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- j=0;i=0;c=0;fuhao=9;//2進制轉10進制
- while(a!=0)
- {
- r=a%10;
- s[i++]=r;
- a=a/10;
- }
- for(j=i-1;j>=0;j--)
- {
- c=c*2+s[j];
- }
- while(c!=0)
- {
- write_date(0x30+c%10);
- c=c/10;
- }
- write_date(0x3d);
- c=0;a=0;fuhao=0;
- } break;
- case 21:{
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- i=0; fuhao=10;//10進制轉2進制
- while(a!=0)
- {
- r=a%2;
- write_date(0x30+r);
- y=a/2;
- a=y;
- }
- write_date(0x3d);
- a=0;fuhao=0;
- } break;
- case 22:{
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- fuhao=11;//10進制轉16進制
- while(a!=0)
- {
- r=a%16;//循環求余
- if(r>=0&&r<=9)//一位一位輸出
- write_date(0x30+r);
- if(r>=10&&r<=15)
- write_date(0x57+r);
- y=a/16;
- a=y;
- }
- write_date(0x78);
- write_date(0x30);
- write_date(0x3d);
- a=0;fuhao=0;
- } break;
- case 23:{
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- j=0;i=0;c=0;fuhao=12;//2進制轉16進制
- while(a!=0)
- {
- r=a%10;
- s[i++]=r;
- a=a/10;
- }
- for(j=i-1;j>=0;j--)//2進制先轉為10進制
- {
- c=c*2+s[j];
- }
- while(c!=0)
- {
- r=c%16;
- if(r>=0&&r<=9)
- write_date(0x30+r);//得到的10進制再轉為16進制
- if(r>=10&&r<=15)
- write_date(0x57+r);
- y=c/16;
- c=y;
- }
- write_date(0x78);
- write_date(0x30);
- write_date(0x3d);
- a=0;c=0;fuhao=0;
- } break;
- }
- }
- P1=0xfb;
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- { delay(5);
- temp=P1;
- temp=temp&0xf0;
- if(temp!=0xf0)
- {
- temp=P1;
- switch(temp)
- {
- case 0xeb:num=24; break;
- case 0xdb:num=25; break;
- case 0xbb:num=26; break;
- case 0x7b:num=27; break;
- }
- }
- while(P1!=0xfb);
- switch(num)
- {
- case 24:{
- write_date(0x53);
- write_date(0x69);
- write_date(0x6e);
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- fuhao=13;i=0;//sin
- if(a>=0&&a<=360)
- {
- c=(long)((sin((float)a*Pi/180))*1000);
- while(c!=0)
- {
- write_date(0x30+c%10);
- c=c/10;i++;
- if(i==3)
- write_date(0x2e);
- }
- write_date(0x30);
- write_date(0x3d);
- i=0;fuhao=0;a=0;c=0;
- }
- } break;
- case 25:{
- write_date(0x43);
- write_date(0x6f);
- write_date(0x73);
- write_com(0x80+0x0f);
- lcd_clean();
- write_com(0x04);
- fuhao=14;i=0;//cos
- if(a>=0&&a<=360)
- {
- c=(long)((cos((float)a*Pi/180))*1000);
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
計算器.rar
(446.67 KB, 下載次數: 36)
2019-3-20 19:12 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|