|
這個(gè)設(shè)計(jì)是本人今天搞定出來的特意分享給大家學(xué)習(xí)學(xué)習(xí)數(shù)碼管顯示+矩陣鍵盤的使用,怕新手不會(huì)接線,我在里面加了個(gè)仿真proteus,可以方便大家一目明了
功能:計(jì)算器可以 加減乘除,4為數(shù)碼管顯示數(shù)值
本設(shè)計(jì)絕對(duì)可以用,真實(shí)可用(希望能幫到大家)
一起加油哈
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (33.15 KB, 下載次數(shù): 60)
下載附件
2021-6-18 17:29 上傳
單片機(jī)源程序如下:
- # include<STC12C5A60S2.h>//單片機(jī)型號(hào)頭文件
- # define uchar unsigned char
- # define uint32 unsigned long int
- # define sint32 signed long int
- # define vtime 3000 //定時(shí)3ms,一幀8*3=24ms,頻率=40Hz
- //共陰數(shù)碼管段碼表
- uchar code distable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X00,0x40,0x31};
- //位選碼表
- uchar code numi[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- //顯示緩存
- uchar V_ram[]={0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10};
- uchar error=0,wi=0,dot1=0,dot2=0,dot=0xff; //位選循環(huán)變量
- uint32 num1=0,num2=0,num=0,sum=0;
- void dispsum();
- void delay(uchar);
- uchar scan_key();
- main() //m1:m0 00=標(biāo)準(zhǔn); 01=推挽; 10=輸入; 11=開漏輸出
- {
- uchar ni,nj,fn='+',key_V=0,dotp=0,j,k,i=0;
- uint32 temp=0;
- //m1:m0 00=標(biāo)準(zhǔn); 01=推挽; 10=輸入; 11=開漏輸出
- P1M1 = 0X0f;
- P1M0 = 0XF0; //設(shè)定低4位為輸入,高4位為輸出
- P0M1 = 0X00;
- P0M0 = 0Xff;
- P2M1 = 0X00;
- P2M0 = 0Xff; //設(shè)定P0,P2推挽輸出
- TMOD = 0X01; //設(shè)定定時(shí)器0為16位計(jì)數(shù)方式
- TH0 = (65536-vtime )/256;
- TL0 = (65536-vtime )%256; //賦定時(shí)器0初值
- ET0 = 1; //開定時(shí)器0中斷
- EA = 1; //開總中斷
- TR0 = 1; //啟動(dòng)定時(shí)器0計(jì)數(shù)
- //sum=123456;
- while(1)
- {
- key_V=scan_key();
- //dispsum();
- if(key_V)
- {
- //有鍵按下
- key_V--;
- switch(key_V)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- if((num+i)==0)
- { //如果是第一個(gè)數(shù)字輸入,則清黑屏
- dot=0xff; //關(guān)閉小數(shù)點(diǎn)
- for(j=0;j<8;j++)
- V_ram[j]=0x10; //清黑屏
- }
- num=num*10+key_V; //鍵盤輸入的數(shù)字轉(zhuǎn)化為十進(jìn)制的數(shù)值
- if(i==8) //如果顯示緩沖滿了
- {
- i=7;
- for(j=0;j<7;j++)
- V_ram[j]=V_ram[j+1];//顯示緩存串行移位
- }
- V_ram[i]=key_V; //鍵值放入顯示緩存
- i++;
- break;
- case 10: //dot 小數(shù)點(diǎn)符號(hào)
- dotp=i; //記錄下小數(shù)點(diǎn)位置
- dot=dotp-1; //顯示小數(shù)點(diǎn)
- break;
- case 11: //+ 加法符號(hào)
- for(j=0;j<8;j++)
- V_ram[j]=0x10; //清黑屏
- num1=num; //獲取從鍵盤輸入的第一個(gè)數(shù)值
- if(dotp==0)
- {
- dot1=0;
- }
- else
- {
- dot1=i-dotp;
- }
- ni=i;
- dotp=0;
- dot=0xff;
- num=0;
- fn='+';
- i=0;
- break;
- case 12: //- 減法符號(hào)
- for(j=0;j<8;j++)
- V_ram[j]=0x10; //清黑屏
- num1=num; //獲取從鍵盤輸入的第一個(gè)數(shù)值
- if(dotp==0)
- {
- dot1=0;
- }
- else
- {
- dot1=i-dotp;
- }
- ni=i;
- dotp=0;
- dot=0xff;
- num=0;
- fn='-';
- i=0;
- break;
- case 13: //* 乘法符號(hào)
- for(j=0;j<8;j++)
- V_ram[j]=0x10; //清黑屏
- num1=num; //獲取從鍵盤輸入的第一個(gè)數(shù)值
- if(dotp==0)
- {
- dot1=0;
- }
- else
- {
- dot1=i-dotp;
- }
- ni=i;
- dotp=0;
- dot=0xff;
- num=0;
- fn='*';
- i=0;
- break;
- case 14: // / 除法符號(hào)
- for(j=0;j<8;j++)
- V_ram[j]=0x10; //清黑屏
- num1=num; //獲取從鍵盤輸入的第一個(gè)數(shù)值
- if(dotp==0)
- {
- dot1=0;
- }
- else
- {
- dot1=i-dotp;
- }
- ni=i;
- dotp=0;
- dot=0xff;
- num=0;
- fn='/';
- i=0;
- break;
- case 15: //= 等于符號(hào)
- if(dotp==0) //計(jì)算第二個(gè)運(yùn)算數(shù)的小數(shù)位數(shù)
- {
- dot2=0;
- }
- else
- {
- dot2=i-dotp;
- }
- dotp=0;
- nj=i;
- temp=1;
- if(fn!='*')
- { if(dot1>dot2) //第一個(gè)運(yùn)算數(shù)與第二個(gè)運(yùn)算進(jìn)行對(duì)齊
- {
- for(j=dot1-dot2;j>0;j--)
- {
- //if(num>0x19999999)error=1;
- num=num*10;
- nj++;
- if(nj>9)
- {
- j--;
- for(k=j;k>0;k--)
- num1=num1/10;
- dot1=dot1-j;
- break;
- }
- }
- }
- else
- {
- for(j=dot2-dot1;j>0;j--)
- {
- //if(num1>0x19999999)error=1;
- num1=num1*10;
- ni++;
- if(ni>9)
- {
- j--;
- for(k=j;k>0;k--)
- num=num/10;
- dot2=dot2-j;
- break;
- }
- }
- }
- }
- //準(zhǔn)備好后,進(jìn)行運(yùn)算
- if(fn=='+') //做加法運(yùn)算
- {
- sum=num+num1;
- if(sum<(num|num1))error=1;
- dispsum(); //顯示對(duì)齊后的運(yùn)算結(jié)果
- if(dot2>dot1) //顯示實(shí)際小數(shù)點(diǎn)的位置
- dot=dot-dot2;
- else
- dot=dot-dot1;
- i=0; //計(jì)算結(jié)束,初始化關(guān)鍵變量
- num1=0;
- num=0;
- break;
- }
- if(fn=='-') //做減法運(yùn)算
- {
- if(num1<num) //判斷結(jié)果是負(fù)還是正
- {
- sum=num-num1;
- }
- else
- sum=num1-num;
- dispsum(); //顯示對(duì)齊后的運(yùn)算結(jié)果
- if(num>num1) //是負(fù)數(shù)則第一位顯示“-”,其它位順序往后顯示
- {
- for(j=7;j>0;j--)
- V_ram[j]=V_ram[j-1]; //順序往后顯示
- V_ram[0]=0x11; //第一位顯示“-”
- dot++; //小數(shù)點(diǎn)也順延一位
- }
- if(dot2>dot1) //顯示實(shí)際小數(shù)點(diǎn)的位置
- dot=dot-dot2;
- else
- dot=dot-dot1;
- i=0; //計(jì)算結(jié)束,初始化關(guān)鍵變量
- num1=0;
- num=0;
- break;
- }
- if(fn=='*') //做乘法運(yùn)算
- {
- sum=num1*num;
- if((ni+nj)>10)error=1;
- dispsum(); //顯示對(duì)齊后的運(yùn)算結(jié)果
- //if(dot2>dot1) //顯示實(shí)際小數(shù)點(diǎn)的位置
- dot=dot-dot2-dot1;
- //else
- // dot=dot-dot1-dot1;
- i=0; //計(jì)算結(jié)束,初始化關(guān)鍵變量
- num1=0;
- num=0;
- break;
- }
- if(fn=='/') //做除法運(yùn)算
- {
- sum=num1/num;
- dispsum(); //顯示對(duì)齊后的運(yùn)算結(jié)果,對(duì)于除法,就是實(shí)際結(jié)果
- temp=num1%num; //顯示小數(shù)部分
- for(j=dot;j<7;j++)
- {
- temp=temp*10;
- V_ram[j+1]=temp/num;
- temp=temp%num;
- if(temp==0)break;
- }
- i=0; //計(jì)算結(jié)束,初始化關(guān)鍵變量
- num1=0;
- num=0;
- break;
- }
- break;
-
- default:
- break;
- }
- delay(200);//延時(shí)去抖
- }
-
- }
- }
- void t0_isp() interrupt 1
- {
- uchar dm,wx;
- TH0 = (65536-vtime )/256;
- TL0 = (65536-vtime )%256; //賦定時(shí)器0初值
- dm=distable[V_ram[wi]]; //取顯示段碼
- wx=numi[wi]; //取位選碼
- P2=0x00; //關(guān)顯示
- //P0=dm; //段碼賦給P0口
- if(dot==wi)
- {
- P0=dm|0x80; //點(diǎn)亮位選的那個(gè)數(shù)碼管+小數(shù)點(diǎn)
- }
- else
- {
- P0=dm; //點(diǎn)亮位選的那個(gè)數(shù)碼管
- }
- P2=wx;
- wi++;
- if(wi==8)wi=0;
- }
- /////////////////////////////////////
- uchar scan_key()
- {
- uchar i,j,vlume=0,temp[4]={0xef,0xdf,0xbf,0x7f};
- for(j=0;j<4;j++)
- {
- P1=temp[j];
- i=P1|0xf0;
- if(i != 0xff) //判斷按鍵
- { //有鍵按下
- i=~i;
- if(i==4)i=3;
- if(i==8)i=4;
- i--; // 計(jì)算按鍵所在行號(hào)(0--3)
- vlume=i*4+j+1; //計(jì)算鍵值
- //delay(200);//延時(shí)去抖
- }
- }
- return vlume;
- }
- ////////////////////////////////////////
- void delay(uchar k )
- {
- uchar x,y,z;
- for(x=k;x>0;x--)
- for(y=20;y>0;y--)
- for(z=250;z>0;z--);
- }
- ////////////////////////////////////////
- void dispsum()
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
51單片機(jī)計(jì)算器 數(shù)碼管顯示.zip
(149.9 KB, 下載次數(shù): 41)
2021-6-18 17:21 上傳
點(diǎn)擊文件名下載附件
51單片機(jī) 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|