單片機 串口計算器 實驗報告_第1頁
單片機 串口計算器 實驗報告_第2頁
單片機 串口計算器 實驗報告_第3頁
單片機 串口計算器 實驗報告_第4頁
單片機 串口計算器 實驗報告_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、二0一三年 單片機課程設計報告姓 名 王志超 學 號 1162910228 指導老師 陸曉春 完成時間 2013.12.27 河 海 大 學2013年12月 2013年電科專業(yè)單片機課程設計報告 Dec.20131、 作品簡介本作品的名稱是串口計算器,其功能是計算機將數據或者字符串發(fā)送給單片機,單片機根據要求可以把用戶的相應指令進行整合運算,并把這個數據的結果顯示到串口助手和數碼管上,完成計算的功能。其中還涉及到了浮點數的運算,我們將浮點數精確到了一位,在這個計算其中還可以對負數進行運算,并將負數顯示到數碼管和串口助手。1、串行通信功能:實驗板和PC電腦通過USB線相連,使MCU和PC軟件“串

2、口助手”能夠進行串行通信。 (1)當實驗板上電時默認波特率為9600bps,并發(fā)送歡迎詞和提示詞,例如“Welcome to Calculator V1.0”,"You can press key1 and key2to change baud rate.". (2)當實驗板上按鍵1按下時波特率變更為4800bps,按鍵2按下時波特率變更為9600bps,并用兩個LED燈指示相應的波特率。2、計算器功能通過串口助手發(fā)送框發(fā)送需要計算的公式,例如20*4=,MCU收到后解析公式并計算結果,將結果返回給串口,例如“The result is 80”,同時將計算結果顯示在數碼管上

3、,具體細節(jié)如下:(1)可以進行加(+)、減(-)、乘(*)、除()、取余(%)運算;(2)整形、浮點型運算;(3)當計算結果為整形數時,有效的運算結果范圍是-9999999,超過此結果,返回相應的提示符,例如“The result is out of range.”,數碼管上提示“Err”;(4)當計算結果為浮點數時,有效的運算結果范圍是-99.9999.9,數碼管上顯示時保留1位小數點,超過此結果,返回相應的提示符,例如“The result is out of range.”,數碼管上提示“Err”。期間,本人編寫了串口助手程序,方便本人在調試過程中發(fā)現錯誤,改正錯誤。這是一個副產品。2、

4、作品整體方案 本作品主要是,實現串口計算功能。整體思路如下所示:串口助手字符顯示Stc89C52單片機數碼管波特率顯示按鍵波特率選擇數碼管結果顯示3、 程序設計思路對于這個作品,我們總共分了幾個模塊:主函數、計算函數、串口函數、數碼管函數、按鍵函數四部分組成。下面就是對具體函數思路的解析:字符串的讀取和識別算式的分解字符串的輸入運算符的提取判定算式結束數的提取串口助手顯示結果的輸出數碼管顯示(1)對于主函數,我最初的思路是在主函數里調用各個函數,加上函數聲明即可。后來在程序出錯的情況下,我無法對程序做出高效準確地修改,故我采用了頭文件的方法,這也是老師上課提到過的。為此我還特意到網上學習了頭文

5、件的撰寫。主函數就是定義了各個變量,對整體做了一個大概的構思,編寫了主要思路和各個中斷函數程序如下所示:主函數:uchar block12; 暫存數組uchar i=0,a,b=0;uchar flag=0;uchar code prompt1 = "welcome to use the uart calculator based on the 51n"uchar code prompt2 = "Now you are entering a new world. tn"uchar code prompt3 = "Please choose yo

6、ur own bps, k1:9600bps(默認), k2:4800bps. tn"uchar code prompt8 = "Err"float result; extern uchar sym; 這是一個外部變量void main()Serialport();sendstring(prompt1);sendstring(prompt2);sendstring(prompt3);keyfirst();while(1) if(flag=1) flag=0;result=trans(block); 轉換為字符并發(fā)送到串口助手顯示b=0;a=0;sym=0; 符號位

7、for(i=0;i<12;i+) 數組清零,以防干擾下次接收blocki=0; keycheck(); 鍵盤檢測 showdigitron(); 在數碼管上顯示 對于串口和按鍵的問題,我也采用了中斷處理的方法,在中斷中,我對按鍵做了處理,即選擇對應的波特率,這里這樣做不會對主程序的結構造成影響,串口也是采用中斷傳輸的,這樣就可以使數據可以在需要的時候傳輸,程序如下:/*串行口中斷函數*/void Serial() interrupt 4 if(RI)RI=0;a=SBUF;blockb+=SBUF;if(a=61) /檢測到等號flag=1; ES=0;SBUF=a;while(!TI)

8、;TI=0;ES=1; 對于按鍵我們使用的是外部中斷1,為的是出錯是可以有高一點的中斷將其打斷,程序如下:void Key() interrupt 2char aa;key_flag=1;p36=1;if(p33=1)key_mem=2;elsekey_mem=1;aa=p33;while(!aa)/松手檢測aa=p33;delay(); /目的去抖動p36=0; /接口置零才可以,勿忘(2)對于計算函數的解決,我分別采用數組和指針的方法對數字進行分離,由于算式是以字符串的形式輸入的,故我們對于數字只要識別0-9即可,當我們識別了運算符的時候前一位就是第一個數的字符串長度,運算符后面的就是第二

9、個字符串的開始,當檢測到“=”的時候就是第二個字符串的長度,這樣就可以把兩個字符串給提取出來。當我檢測到運算符的時候,我會進行分類,例如我檢測到了“+”,則使用case(+)來進行分類,滿足運算需求。字符串的提取程序如下:for(m=0;(*p!=+)&&(*p!=-)&&(*p!=*)&&(*p!=/)&&(*p!=%);m+) /m記錄第一個運算數的位數num11m=*p; /提取第一個操作數p+; sign=*p+; /將運算符賦給變量sign n=z-m-2; /n記錄第二個操作數的位數for(i=0;i<n;i+)

10、num22i=*p+; /第二個操作數 num1=convert(m,num11); /將第一個操作數轉換為十進制浮點數f1=f; /記錄是整數還是浮點數f=0; /注意f是全局變量,一定要在下次使用前將其清零num2=convert(n,num22);f2=f;f=0; /全局變量清零運算程序:switch(sign)/進行運算case '+':num3=num1+num2;break;case '-':if(num1>=num2)num3=num1-num2;elsenum3=num2-num1;sym=1;break;case '*'

11、:num3=num1*num2;break;case '/':if(num2=0) /除數是0的情況SBUF='n'while(!TI);TI=0;sendstring(prompt6);false=1;/transdigitron(int)num3); /由于下一句返回,必須在此處改變數碼管的值return 0;elsenum3=num1/num2;break;case '%':if(num2=0)/除數是0的情況SBUF='n'while(!TI);TI=0;sendstring(prompt6);false=1;/出錯標志t

12、ransdigitron(int)num3); /由于下一句返回,必須在此處改變數碼管的值return 0;elsenum3=(int)num1%(int)num2;/只有整形數才能進行取余運算break; default:break;數碼管的點亮,我把輸出的結果保存成數組,然后再通過數碼管輸出:數碼管的檢測:void transdigitron(uint number)int a=1;if(sym=0)&&(number>9999) /若大于9999b0=12;b1=12;b2=11;b3=0;/顯示“Err”l=3;return;/返回主函數,不執(zhí)行后面的程序fals

13、e=1;if(sym=1)&&(number>999)b0=12;b1=12;b2=11;b3=0;l=3;return;/返回主函數,不執(zhí)行后面的程序 false=1;if(false=1) /false=0; /清零出錯標志c0=12;c1=12;c2=11;c3=0;l=3;return;/返回主函數,不執(zhí)行后面的程序l=0;/l是全局變量,每一次計算前將l清零,防止下次干擾!while(a!=0) /分解各位,存入數組b中a=number/10;cl+=number%10;number=number/10; if(l=1)&&(f1|f1) cl+

14、=0;if(sym)cl+=13; /將負號放入數組中對于數碼管的顯示:void showdigitron()char j;for(j=0;j<l;j+) P1=block1cj;P0=block2j;if(j=1)&&(false=0)if(f1|f2) /浮點數P1&=0x7f;delaydigitron(); /數碼管的延時顯示 對于波特率的選擇我使用的是按鍵,采用選擇語句,可以使之有不同的選擇:void keycheck()if(key_flag=1)key_flag=0;switch(key_val)case 1:TH1=0xfa;TL1=0xfa;sy

15、m=0;transdigitron(4800);break; case 2:TH1=0xfd;TL1=0xfd;sym=0;transdigitron(9600);break; default:break;這就是我程序的大體思路,通過編寫頭文件,實現了各個函數間的相互調用,頭文件的編寫框架:#ifndef _Key_press_H #define _Key_press_Hsbit p33=P33;sbit p35=P35;sbit p36=P36;extern char key_flag,key_val;void keyfirst();void keycheck();void delay();

16、#endif使用的時候將頭文件包含到要調用的函數即可。4、 遇到的問題及解決辦法在此次課程設計中,我遇到了問題,有問題是正常的,關鍵是看如何解決,故我將遇到的問題和解決方法列下:(1) 程序過長,造成修改程序不便。 解決:通過網上學習頭文件的寫法,利用頭文件來實現各個函數間的相互調用,利用各個函數的聯系來實現功能,這樣子更加明了,結構更加條理。(2) 數碼管顯示0的問題。開始的時候,我采用的是填充的方法來進行數碼管顯示的,即負號放在最前,數字放在最后,中間使用0填充,這樣子數碼管上就有很多0,造成閱讀的障礙。解決:采用數組和指針的方法,使字符串可以按順序進入數組中,對數組的循環(huán)掃描,從而可以是

17、數碼管正常顯示。(3) 浮點數的問題。浮點數的問題開始的時候我們不知道如何讓小數點后的數顯示,這樣子就造成了困倦。解決:通過小數乘以“10”便可將小數變成整數,然后對應數碼管顯示即可。(4) 整數的顯示。 開始時,認為整數可以一下顯示的,后來發(fā)現不可以。解決:采用數值除以十然后取余數,循環(huán)執(zhí)行,便可實現。5、小結 在這次課程設計中,個人收獲頗多。首先,我是從頭把c語言看了一遍,是自己在c語言方面又學到了一些新的東西。其次,在做課程設計期間,我又把頭文件學習了一下,這樣我在編寫一些比較長的程序的時候就可以采用這種方法,是程序變得調理清晰,易于解讀,對于程序中出現的錯誤就更可以修改了,方便快捷。第三,在這次課程設計中,我也找到了自己的薄弱項,就是對程序的整體把握不夠,雖然可以條理清晰,但是卻無法對細節(jié)進行好的優(yōu)化。通過這次課程設計設我也明白了優(yōu)化的重要性。第四,在課程設計中,我也體會到了幫助別人的快樂,自己是一個小組長,在幫助組員的過程中,我積極主動,在幫

溫馨提示

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

評論

0/150

提交評論