單片機(jī)實(shí)驗(yàn)報(bào)告-計(jì)算器_第1頁(yè)
單片機(jī)實(shí)驗(yàn)報(bào)告-計(jì)算器_第2頁(yè)
單片機(jī)實(shí)驗(yàn)報(bào)告-計(jì)算器_第3頁(yè)
單片機(jī)實(shí)驗(yàn)報(bào)告-計(jì)算器_第4頁(yè)
單片機(jī)實(shí)驗(yàn)報(bào)告-計(jì)算器_第5頁(yè)
已閱讀5頁(yè),還剩14頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

頁(yè)共14頁(yè)1.3矩陣按鍵模塊 計(jì)算器的輸入通過(guò)4X4的矩陣按鍵來(lái)實(shí)現(xiàn),由于軟件上做了相應(yīng)的映射處理,因此該4X4按鍵可以實(shí)現(xiàn)在極少代碼更改下隨意安排每個(gè)按鍵的實(shí)際意義。矩陣按鍵通過(guò)行列掃描的方式快速求出當(dāng)前的按下按鍵并等待起彈起以防止重復(fù)觸發(fā):1.4串口連接模塊 由于使用Proteus仿真,這里的串口電路進(jìn)行了簡(jiǎn)化,沒(méi)有使用實(shí)際中將會(huì)用于進(jìn)行電平轉(zhuǎn)換的232芯片,而直接使用串口觀察控件進(jìn)行串口接收以及顯示:二、C51程序設(shè)計(jì)由于本系統(tǒng)對(duì)系統(tǒng)的響應(yīng)速度要求并不高,不需要進(jìn)行高速的大量數(shù)據(jù)運(yùn)算操作,因此不采用匯編方式編寫(xiě)程序。使用C語(yǔ)言編寫(xiě)程序能夠清晰地分析系統(tǒng)的整體思路。本程序的主要思想是狀態(tài)機(jī),利用狀態(tài)機(jī)的不同狀態(tài)對(duì)程序的流程進(jìn)行分段控制,在本系統(tǒng)中,較大限度的提高了系統(tǒng)的運(yùn)行效率,同時(shí)具有了便于分析、改進(jìn)和查錯(cuò)的天然優(yōu)勢(shì)2.1程序功能描述與設(shè)計(jì)思路2.1.1、按鍵服務(wù)函數(shù):將4X4矩陣按鍵封裝至按鍵服務(wù)函數(shù)中,利用映射表(數(shù)組)對(duì)4X4的對(duì)應(yīng)按鍵進(jìn)行鍵值映射,這樣不僅僅完成了按鍵判斷的函數(shù)封裝更便于實(shí)際操作時(shí)對(duì)按鍵的定義的靈活改動(dòng),另外,按鍵的返回值采用ASCII碼形式,這樣更加利于程序上的可讀性;2.1.2、LCD驅(qū)動(dòng)函數(shù):按照LM016模塊的操作時(shí)序編寫(xiě)的LM016(LCD1602液晶)的驅(qū)動(dòng)函數(shù),使用C和H文件組合的形式既完成了底層的液晶驅(qū)動(dòng)又開(kāi)放了操作液晶的接口函數(shù),使整體程序更加清晰明了;2.1.3、結(jié)果顯示函數(shù):由于計(jì)算結(jié)果涉及到小數(shù)點(diǎn)、負(fù)數(shù)以及長(zhǎng)度的不確定性,這里直接通過(guò)調(diào)用stdio.h中的sprintf字符串格式化函數(shù)進(jìn)行格式化,得到15個(gè)字符長(zhǎng)度的ASCII形式數(shù)據(jù)顯示,并在程序中進(jìn)行范圍限定以避免數(shù)據(jù)過(guò)大而產(chǎn)生顯示不完整造成結(jié)果“不正確”的現(xiàn)象。同時(shí)該函數(shù)還通過(guò)調(diào)用串口輸出函數(shù)對(duì)單片機(jī)串口進(jìn)行輸出,可在計(jì)算機(jī)上位機(jī)端得到每次的計(jì)算結(jié)果信息;2.1.4、狀態(tài)機(jī)控制函數(shù):該函數(shù)直接在main函數(shù)的內(nèi)部實(shí)現(xiàn),并融合狀態(tài)機(jī)的程序思想,利用狀態(tài)機(jī)判斷計(jì)算器輸入時(shí)的各種可能狀態(tài)并在不同程序狀態(tài)中跳轉(zhuǎn)實(shí)現(xiàn)靈活的程序流程控制,實(shí)踐表明這種方式是非常適合計(jì)算器的程序設(shè)計(jì)的,能較大限度地提高系統(tǒng)的運(yùn)行效率;2.1.5、串口服務(wù)函數(shù):串口服務(wù)主要負(fù)責(zé)實(shí)現(xiàn)單片機(jī)向計(jì)算機(jī)上位機(jī)端的數(shù)據(jù)結(jié)果輸出以及靈活的字符串顯示。2.2程序流程圖2.2.1、系統(tǒng)總框圖2.2.2、計(jì)算器狀態(tài)機(jī)流程轉(zhuǎn)換圖三、仿真方案與仿真結(jié)果3.1仿真方案1、硬件仿真使用Proteus7.8進(jìn)行硬件仿真。2、軟件仿真使用Keil4For51Debug工具進(jìn)行軟件編寫(xiě)和仿真3、硬件軟件聯(lián)調(diào)利用Proteus7.8和Keil4進(jìn)行聯(lián)合軟硬件調(diào)試,方便查錯(cuò)和仿真展現(xiàn)3.2測(cè)試結(jié)果及分析3.2.1測(cè)試結(jié)果(仿真截圖)1、加、減、乘、除基本運(yùn)算展示:2、連續(xù)運(yùn)算展示:3、溢出和除0判斷展示:4、串口通信展示:5、開(kāi)機(jī)效果顯示:3.3.2測(cè)試分析與結(jié)論根據(jù)上述測(cè)試數(shù)據(jù),綜上所述,本設(shè)計(jì)總體來(lái)說(shuō)可以達(dá)到大部分設(shè)計(jì)要求。四、總結(jié)與心得經(jīng)過(guò)本次的實(shí)驗(yàn)設(shè)計(jì)學(xué)習(xí),又一次深刻感受到了51單片機(jī)雖然已經(jīng)過(guò)去幾十年,現(xiàn)在也不斷地收到16位、32位低價(jià)單片機(jī)的沖擊,但仍然是一款性能優(yōu)越的單片機(jī),在處理生活中常用的簡(jiǎn)單任務(wù)時(shí),51單片機(jī)依然能夠煥發(fā)出青春般的光彩。同時(shí),51單片機(jī)也是學(xué)習(xí)和理解其他高級(jí)單片機(jī)的最好的入門(mén)平臺(tái),本次的實(shí)驗(yàn)也將增強(qiáng)了我對(duì)學(xué)習(xí)好其他高級(jí)單片機(jī)的決心和信心。五、思考題1.描述完整所設(shè)計(jì)的計(jì)算器能完成的各項(xiàng)功能及實(shí)現(xiàn)方法。(如幾位數(shù)以?xún)?nèi)的運(yùn)算;連加;復(fù)合運(yùn)算等等)本實(shí)例實(shí)現(xiàn)了加減乘除基本運(yùn)算、連續(xù)運(yùn)算、最大長(zhǎng)度14位的數(shù)據(jù)輸入、超過(guò)14位數(shù)據(jù)后程序?yàn)楸苊獠涣硷@示自動(dòng)顯示溢出2.計(jì)算器設(shè)計(jì)過(guò)程中碰到的問(wèn)題及解決的方法?使用時(shí)原本打算使用double型變量,但在實(shí)際測(cè)試中并沒(méi)有發(fā)現(xiàn)精度很高,通過(guò)聯(lián)合調(diào)試發(fā)現(xiàn)KEILC51編譯器將double型自動(dòng)轉(zhuǎn)換為float型;3.如何實(shí)現(xiàn)掉電保護(hù)?使用E2PROM或者外部的SD卡等存儲(chǔ)設(shè)備,通過(guò)一定的時(shí)序操作控制這些外部設(shè)備實(shí)現(xiàn)存儲(chǔ)數(shù)據(jù)的接口,在每一步計(jì)算操作后都將過(guò)程和結(jié)果存儲(chǔ)到存儲(chǔ)設(shè)備中,在下次上電后直接讀取實(shí)現(xiàn)掉電保護(hù);4.日常生活中計(jì)算器光敏單元的功能及實(shí)現(xiàn)原理?光敏單元可看作為一個(gè)電流源,通過(guò)電阻進(jìn)行簡(jiǎn)單的I/V轉(zhuǎn)換,然后用ADC轉(zhuǎn)換為數(shù)字量,通過(guò)單片機(jī)處理后調(diào)節(jié)液晶偏壓或占空比來(lái)調(diào)節(jié)顯示對(duì)比度以實(shí)現(xiàn)不同光強(qiáng)下的正常顯示;5.如何與上位機(jī)進(jìn)行計(jì)算結(jié)果的通信?本實(shí)例中已經(jīng)簡(jiǎn)單實(shí)現(xiàn)了基于串口的單片機(jī)與計(jì)算機(jī)上位機(jī)之間的通信,不過(guò)是單向的,為了實(shí)現(xiàn)真正的通信,可定義相關(guān)協(xié)議,通過(guò)串口收發(fā)管理這些數(shù)據(jù)和操作來(lái)實(shí)現(xiàn)。附錄1:整體電路原理圖附錄2:部分源程序/*頭文件引用部分*/#include"mySys.h"#include"LM016.h"#include"stdio.h"#include"MyUsart.h"/*端口定義部分*/#definePORT_KEYP1/*全局變量*/floatCalNum1=0; //待計(jì)算數(shù)1floatCalNum2=0; //待計(jì)算數(shù)2floatResNum=0; //計(jì)算結(jié)果unsignedcharAppendNum=0;//判斷是否為連續(xù)模式unsignedcharNumsBegin=0; //判斷是否真的開(kāi)始有數(shù)字輸入這里是為了避免重復(fù)輸入前面的0unsignedcharFirstZero=0; //第一個(gè)是否為0unsignedcharNumPen=0; //書(shū)寫(xiě)坐標(biāo),會(huì)隨著數(shù)字的輸入而向后移動(dòng)unsignedcharAllNumsLen;//當(dāng)前待計(jì)算數(shù)和運(yùn)算符總長(zhǎng)度,定義該變量是為了避免式子過(guò)長(zhǎng)codeunsignedcharCalSymbolTable[]={0,'+','-','*','/'}; //運(yùn)算符表unsignedcharCalSymbol=0; //運(yùn)算符unsignedcharSysStatus=0; //程序運(yùn)行狀態(tài) //0程序初始化狀態(tài)1正在輸入第一個(gè)數(shù)2正在輸入第二個(gè)數(shù)3得到運(yùn)算結(jié)果/*函數(shù)聲明部分*/unsignedcharKeyScan(void);voidShowLogo(void);voidShowCalResult(floatValue);/*函數(shù)實(shí)現(xiàn)部分*/voidmain(void){ unsignedcharTempKey; LM016_Init(); MyUsart_Init(); MyUsart_Print("Thisis51CalculatorProgram!"); MyUsart_Print("UsartMode:TXBAD=19200bps"); ShowLogo(); //顯示LOGO MyUsart_Print("SystemInitDone!HaveFun!"); while(1) { switch(SysStatus) { case0://【程序初始化狀態(tài)】 LM016_Clear();//清屏 CalNum1=0; CalNum2=0; ResNum=0; NumPen=0; AppendNum=0; NumsBegin=0; FirstZero=0; AllNumsLen=0; CalSymbol=0; SysStatus=1;//進(jìn)入正在輸入第一個(gè)數(shù)狀態(tài) break; case1://【正在輸入第一個(gè)數(shù)字】 TempKey=KeyScan(); if(!TempKey)break;//沒(méi)有按鍵按下則快速跳出 if(TempKey>='0'&&TempKey<='9')//*****數(shù)字鍵 { if(!NumsBegin) //現(xiàn)在還沒(méi)有開(kāi)始正式輸入數(shù)字 { if(TempKey=='0') { if(!FirstZero) //第一次輸入0 FirstZero=1;//給了一次輸入0的機(jī)會(huì),后面就不給了 elsebreak; } else { NumsBegin=1;//開(kāi)頭是非零,已經(jīng)開(kāi)始正式輸入數(shù)字了 NumPen=0;//書(shū)寫(xiě)坐標(biāo)歸位,此時(shí)將會(huì)覆蓋原有的0 } } if(AllNumsLen>=10)break;//長(zhǎng)度過(guò)長(zhǎng)則快速跳出不在接受數(shù)字輸入 CalNum1*=10; CalNum1+=(TempKey-'0');//求得當(dāng)前數(shù)值 LM016_PutChar(0,NumPen,TempKey); NumPen++;//書(shū)寫(xiě)坐標(biāo)向右邊移動(dòng) AllNumsLen++; } else //*****符號(hào)鍵 { switch(TempKey) { case'+': case'-': case'*': case'/': if((!NumsBegin)&&(!FirstZero))//若沒(méi)有任何數(shù)字按鍵按下則補(bǔ)充這個(gè)0 { LM016_PutChar(0,0,'0'); NumPen++; } CalSymbol=TempKey; LM016_PutChar(0,NumPen,TempKey); NumPen++; AllNumsLen++; NumsBegin=0; FirstZero=0; AppendNum=0; CalNum2=0;//把第二個(gè)數(shù)值清空 SysStatus=2; break; case'=': ResNum=CalNum1; ShowCalResult(ResNum); FirstZero=0; AppendNum=0; NumsBegin=0; NumPen=0; AllNumsLen=0; SysStatus=3;//進(jìn)入過(guò)度階段 break; case'C': SysStatus=0; break; } break; } case2://【正在輸入第二個(gè)數(shù)字】 TempKey=KeyScan(); if(!TempKey)//沒(méi)有按鍵按下則快速跳出 break; if(TempKey>='0'&&TempKey<='9')//*****數(shù)字鍵 { if(!NumsBegin) //現(xiàn)在還沒(méi)有開(kāi)始正式輸入數(shù)字 { if(TempKey=='0') { if(!FirstZero) //第一次輸入0 FirstZero=1;//給了一次輸入0的機(jī)會(huì),后面就不給了 elsebreak; } else { NumsBegin=1;//開(kāi)頭是非零,已經(jīng)開(kāi)始正式輸入數(shù)字了 if(FirstZero)NumPen--;//書(shū)寫(xiě)坐標(biāo)歸位,此時(shí)將會(huì)覆蓋原有的0 } } if(AllNumsLen>=16)break;//長(zhǎng)度過(guò)長(zhǎng)則快速跳出不在接受數(shù)字輸入 CalNum2*=10; CalNum2+=(TempKey-'0');//求得當(dāng)前數(shù)值 LM016_PutChar(0,NumPen,TempKey); NumPen++;//書(shū)寫(xiě)坐標(biāo)向右邊移動(dòng) AllNumsLen++; } else //*****符號(hào)鍵 { switch(TempKey) { case'=': switch(CalSymbol) { case'+':ResNum=CalNum1+CalNum2;reak; case'-':ResNum=CalNum1-CalNum2;break; case'*':ResNum=CalNum1*CalNum2;break; case'/':ResNum=CalNum1/CalNum2;break; } if((!NumsBegin)&&(!FirstZero))//若沒(méi)有任何數(shù)字按鍵按下則補(bǔ)充這個(gè)0 { LM016_PutChar(0,NumPen,'0'); CalNum2=0; NumPen++; } ShowCalResult(ResNum); FirstZero=0; AppendNum=0; NumsBegin=0; NumPen=0; AllNumsLen=0; SysStatus=3;//進(jìn)入過(guò)度階段 break; case'C':SysStatus=0;break; } } break; case3://【當(dāng)前是過(guò)度階段】 TempKey=KeyScan(); if(!TempKey)break;//沒(méi)有按鍵按下則快速跳出 if(TempKey>='0'&&TempKey<='9')//*****數(shù)字鍵 { LM016_Clear();//清屏 if(!NumsBegin) //現(xiàn)在還沒(méi)有開(kāi)始正式輸入數(shù)字 { if(TempKey=='0') { if(!FirstZero) //第一次輸入0 FirstZero=1;//給了一次輸入0的機(jī)會(huì),后面就不給了 else break; } else { NumsBegin=1;//開(kāi)頭是非零,已經(jīng)開(kāi)始正式輸入數(shù)字了 NumPen=0;//書(shū)寫(xiě)坐標(biāo)歸位,此時(shí)將會(huì)覆蓋原有的0 } } CalNum1=(TempKey-'0');//求得當(dāng)前數(shù)值 這里直接賦值就OK了 CalNum2=0;//把第二個(gè)數(shù)值清空 LM016_PutChar(0,NumPen,TempKey); NumPen=1;//書(shū)寫(xiě)坐標(biāo)向右邊移動(dòng) AllNumsLen=1; SysStatus=1;//進(jìn)入輸入第一個(gè)數(shù)值狀態(tài) } else //*****符號(hào)鍵 { switch(TempKey) { case'+': case'-': case'*': case'/': LM016_Print(0,0,"Ans"); AppendNum=1;

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論