仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (12.11 KB, 下載次數: 31)
下載附件
2020-10-10 21:15 上傳
行列式按鍵及計算器仿真及程序程序如下
- #include"at89x51.h" // C計時器參考
-
- unsigned int da1=0, da2=0, resu=0;
- unsigned char fh=0, zhuangtai=0, key, keyzhi, jianzhi;
- unsigned char code tv[]={0xfe,0xfd,0xfb,0xf7}; //位選數組
- unsigned char code a[]={0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,0x7f,
- 0x6f,0x77,0x7c,0x39,0x5e,
- 0x79,0x71,0x00}; //顯示是P0口的值對應的數組
- unsigned char data led[4] = {0, 16, 16, 16}; //將首位定義成零,在計算器的初始顯示的時候右邊有‘0’表示計算器已經開始工作
- //函數名:delay 時間:
- //作用:在顯示函數中延時
- //說明:延時的時間不用太長即i的峰值不要定太大
- //作者:ymx
- void delay()
- {
- unsigned char i;
- for (i=0; i<200; i++)
- {
- ;
- }
- }
- //函數名:keydeal 時間:
- //作用:掃描鍵盤,通過低電位會將高電位拉成低電位的原理,分別判斷出按鍵的橫縱坐標并將jianzhi傳遞到jianhao函數
- //說明:傳遞0x0f判斷縱坐標,傳遞0xf0判斷橫坐標
- //作者:ymx
- unsigned char keydeal()
- {
- unsigned char x, y;
- P3 = 0xff;
- P3 = 0x0f;
- x = P3;
- P3 = 0xff;
- P3 = 0xf0;
- y = P3;
- jianzhi = x + y;
- return jianzhi;
- }
- //函數名:jisuan 時間:
- //作用:根據記錄的運算符號和兩個數的值計算出結果
- //說明:
- //作者:ymx
- jisuan(void)
- {
- switch(fh)
- {
- case '+':
- resu = da1+da2;
- break;
- case '-':
- resu = da1-da2;
- break;
- case '*':
- resu = da1*da2;
- break;
- case '/':
- resu = da1/da2;
- break;
- }
- fh=0; //將符號清零
- }
- //函數名:jianhao 時間:
- //作用:通過keydeal傳遞的數值判斷按下的按鍵分別代表的意義,如數字,運算符號等。并根據按鍵和按下鍵盤前的狀態來切換此時的狀態
- //說明:
- //作者:ymx
- void jianhao()
- {
- key = keydeal();
- switch(key)
- {
- case 0xff: keyzhi=16; break; //什么鍵都沒有按下
- case 0xd7: keyzhi=0; break;
- case 0xeb: keyzhi=1; break;
- case 0xdb: keyzhi=2; break;
- case 0xbb: keyzhi=3; break;
- case 0xed: keyzhi=4; break;
- case 0xdd: keyzhi=5; break;
- case 0xbd: keyzhi=6; break;
- case 0xee: keyzhi=7; break;
- case 0xde: keyzhi=8; break;
- case 0xbe: keyzhi=9; break;
- case 0xe7:
- keyzhi=10; da1=0; da2=0; fh=0; resu=0; zhuangtai=0;
- led[1]=led[2]=led[3]=16; led[0]=0;break; //按下no鍵時將所有的值與狀態復位,顯示清零
- case 0xb7: keyzhi=11; zhuangtai=3; break; //按下等號鍵將狀態換為3
- case 0x77: keyzhi=12; break;
- case 0x7b: keyzhi=13; break;
- case 0x7d: keyzhi=14; break;
- case 0x7e: keyzhi=15; break;
- }
- //如果按下的鍵在0~9的時候
- if (keyzhi<10)
- {
- if(zhuangtai==1)//如果前一狀態為1。表示完成運算符號的記錄,應當記錄第二個數。狀態切換為2
- {
- zhuangtai=2;
- }
- else if(zhuangtai==3) //如果前一狀態為3,表示已經進行過一次運算并且得出了結果。此時將結果和原有數據清零進行新的運算。狀態切換為0.
- {
- da1=da2=resu=0;
- zhuangtai=0;
- }
- }
- //如果按下的鍵在12~15的時候
- if (keyzhi>11 && keyzhi<16)
- {
- if (zhuangtai==0) //如果前一狀態為0,表示記錄好第一個數,此時應當記錄運算符號。狀態切換為1
- {
- zhuangtai=1;
- }
- else if(zhuangtai==3)//如果前一狀態為3,即表示按下運算符號表示要利用原有結果進行運算。將結果值賦給da1并將
- {
- da1=resu; //并將結果值賦給da1,resu和da2清零。否則原有的值會影響第二次的運算結果。并將狀態切換為1,記錄下運算符號。
- da2=resu=0;
- zhuangtai=1;
- }
- else if(zhuangtai==2)//如果前一狀態為2,即表示已經完成了da1和運算符和da2的記錄。現在不按下等號進行連續運算(如1+2+3)。
- {
- jisuan(); //先計算出前面兩個數的結果
- da1=resu; //將結果賦給da1
- da2=0; //結果和da2清零,并且將狀態切換為1
- resu=0;
- zhuangtai=1;
- }
- }
- }
- //函數名:ysf 時間:
- //作用:記錄下在狀態1時所按下的運算符號
- //說明:
- //作者:ymx
- void ysf()
- {
- switch(keyzhi)
- {
- case 12:
- fh='+';
- break;
- case 13:
- fh='-';
- break;
- case 14:
- fh='*';
- break;
- case 15:
- fh='/';
- break;
- default:
- break;
- }
-
- }
- void move()
- {
- unsigned int linshi=0;
- linshi = keyzhi; //保存下按下的數值
- while(keyzhi != 16)
- {
- jianhao();
- }
- if(led[0]==0&&led[1]==16&&led[2]==16&&led[3]==16&&linshi!=16) //if里的條件表示初始的只是0的時候
- {
- led[0]=linshi; //移位時要將原有的0替換掉否則數顯示的數的前面都會有一個零如:0123
- }
- else
- {
- if(linshi!=16) //如果按下了鍵才開始移位,否則會有空白
- {
- led[3] = led[2];
- led[2] = led[1];
- led[1] = led[0];
- led[0] = linshi;
- }
- }
- if(zhuangtai==0) //狀態為0時記錄第一個數
- {
- da1=da1*10+linshi;
- }
- if(zhuangtai==2) //狀態為2時記錄第二個數
- {
- da2=da2*10+linshi;
- }
- }
- //函數名:jieguo 時間:
- //作用:將結果轉化為可以顯示的形式
- //說明:
- //作者:ymx
- void jieguo() //計算出的結果是 一個整型的書,數碼管并不能直接顯示,需要把它替換成單個的數賦給顯示的led數組
- {
- if(resu<10000) //如果顯示的結果小于5位才顯示
- {
- if (resu>999)
- {
- led[3]=resu/1000; //記錄下千位的值
- }
- else
- {
- led[3]=16;
- }
- if(resu>99)
- {
- led[2]=(resu/100)%10; //記錄下百位的值
- }
- else
- {
- led[2]= 16;
- }
- if(resu>9)
- {
- led[1]=(resu/10)%10;
- }
- else
- {
- led[1]=16;
- }
- if(resu>0)
- {
- led[0]=resu%10;
- }
- else
- {
- led[0]=0;
- }
- }
- else //如果不是小于5位的話,則顯示‘E’表示錯誤
- {
- led[0]=14;
- }
- }
- //函數名:xianshi 時間:
- //作用:位選和顯示不同的數時所對應的P0口的電位值
- //說明:
- //作者:ymx
- void xianshi()
- {
- unsigned char i, k;
- for (i=0; i<4; i++)
- {
- k = led[i];
- P0 = a[k];
- P2 = tv[3-i];
- delay();
- }
- }
- //函數名:main 時間:
- //作用:完成整個程序的循環
- //說明:main函數中除了記錄數值得兩個狀態之外剩下的的狀態里的jianhao函數均是用于切換狀態和復位用的
- // zhuangtai=0表示記錄第一個數,1表示記錄運算符號,2表示記錄第二個數,3表示計算結果并顯示
- //作者:ymx
-
- void main(void)
- {
- while(1)
- {
- while(zhuangtai==0)
- {
- resu=0;
- jianhao();
- if(keyzhi<=9)//判斷是按下的是否是數,是得話才移位和顯示數值否則顯示不變。下面狀態2同
- {
- move();
- }
- xianshi();
- resu=0;
- }
- while(zhuangtai==1)
- {
- led[0]=led[1]=led[2]=led[3]=16;//將顯示清零
- jianhao();
- ysf(); //記錄下運算符號
- }
- while(zhuangtai==2)
- {
- resu=0;
- jianhao();
- if(keyzhi<=9)
- {
- move();
- }
- xianshi();
- }
- while(zhuangtai==3)
- {
- jianhao();
- jisuan();
- jieguo();
- xianshi();
- }
- }
- }
復制代碼
全部資料51hei下載地址:
行列式按鍵及計算器.rar
(46.07 KB, 下載次數: 9)
2020-10-10 20:03 上傳
點擊文件名下載附件
|