版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
-.z.-----總結資料嵌入式課程設計學院:計算機與通信工程學院專業(yè):物聯(lián)網(wǎng)工程班級:物聯(lián)1501:王強**:41501602實驗日期:2017年12月25日實驗名稱:嵌入式課程設計實驗目的:以STC89開發(fā)板為硬件平臺,開發(fā)溫度采集、動態(tài)數(shù)碼管顯示、按鍵響應、與PC串口通訊的綜合程序,實現(xiàn)以下功能:1〕PC上的串口調試助手通過串口給STC89開發(fā)板發(fā)送"GetTemp〞命令。2〕STC89開發(fā)板從串口接收到"GetTemp〞命令后啟動溫度傳感器DS18B20的測溫程序獲取當前溫度,測試完成時將所測得溫度數(shù)據(jù)顯示在動態(tài)數(shù)碼管上。(動態(tài)數(shù)碼管在溫度獲取之前應該顯示"FFFFFFFF〞,只有在獲取溫度后才顯示溫度值)3〕動態(tài)數(shù)碼管顯示出溫度數(shù)據(jù)后,請通過按鍵觸發(fā)STC89開發(fā)板通過串口回送步驟2所測的溫度數(shù)據(jù)給PC上串口調試助手,同時恢復動態(tài)數(shù)碼管顯示為"FFFFFFFF〞。為保證每個同學的實驗都獨立完成,要求回送的數(shù)據(jù)包含自己的**,即如果你的**是20150809,當前溫度值是19.6攝氏度,則在PC上的串口調試助手應該顯示:20150809:19.6°C。硬件電路說明:1〕STC89處理器管腳和晶振電路2〕獨立按鍵獨立按鍵一共5個,分別連接在單片機的P3.0到P3.4口。去抖動的方式,我們采用軟件延時的方法。過程如下:先設置IO口為高電平〔一般上電默認就為高〕,讀取IO口電平確認是否有按鍵按下,如有IO電平為低電平后,延時幾個ms,再讀取該IO電平,如果任然為低電平,說明對應按鍵按下,執(zhí)行相應按鍵的程序。3〕DS18B20溫度傳感器局部DS18B20內部的低溫度系數(shù)振蕩器是一個振蕩頻率隨溫度變化很小的振蕩器,為計數(shù)器1提供一頻率穩(wěn)定的計數(shù)脈沖。高溫度系數(shù)振蕩器是一個振蕩頻率對溫度很敏感的振蕩器,為計數(shù)器2提供一個頻率隨溫度變化的計數(shù)脈沖。初始時,溫度存放器被預置成-55℃,每當計數(shù)器1從預置數(shù)開場減計數(shù)到0時,溫度存放器中存放的溫度值就增加1℃,這個過程重復進展,直到計數(shù)器2計數(shù)到0時便停頓。初始時,計數(shù)器1預置的是與-55℃相對應的一個預置值。以后計數(shù)器1每一個循環(huán)的預置數(shù)都由斜率累加器提供。為了補償振蕩器溫度特性的非線性性,斜率累加器提供的預置數(shù)也隨溫度相應變化。計數(shù)器1的預置數(shù)也就是在給定溫度處使溫度存放器存放值增加1℃計數(shù)器所需要的計數(shù)個數(shù)。DS18B20內部的比擬器以四舍五入的量化方式確定溫度存放器的最低有效位。在計數(shù)器2停頓計數(shù)后,比擬器將計數(shù)器1中的計數(shù)剩余值轉換為溫度值后與0.25℃進展比擬,假設低于0.25℃,溫度存放器的最低位就置0;假設高于0.25℃,最低位就置1;假設高于0.75℃時,溫度存放器的最低位就進位然后置0。這樣,經(jīng)過比擬后所得的溫度存放器的值就是最終讀取的溫度值了,其最后位代表0.5℃,四舍五入最大量化誤差為±1/2LSB,即0.25℃。溫度存放器中的溫度值以9位數(shù)據(jù)格式表示,最高位為符號位,其余8位以二進制補碼形式表示溫度值。測溫完畢時,這9位數(shù)據(jù)轉存到暫存存儲器的前兩個字節(jié)中,符號位占用第一字節(jié),8位溫度數(shù)據(jù)占據(jù)第二字節(jié)。DS18B20測量溫度時使用特有的溫度測量技術。DS18B20內部的低溫度系數(shù)振蕩器能產(chǎn)生穩(wěn)定的頻率信號;同樣的,高溫度系數(shù)振蕩器則將被測溫度轉換成頻率信號。當計數(shù)門翻開時,DS18B20進展計數(shù),計數(shù)門開通時間由高溫度系數(shù)振蕩器決定。芯片內部還有斜率累加器,可對頻率的非線性度加以補償。測量結果存入溫度存放器中。一般情況下的溫度值應該為9位,但因符號位擴展成高8位,所以最后以16位補碼形式讀出。電路圖及管腳如下:4〕串口通信串行通信是將數(shù)據(jù)字節(jié)分成一位一位的形式在一條傳輸線上逐個地傳送,此時只需要一條數(shù)據(jù)線,外加一條公共信號地線和假設干控制信號線。因為一次只能傳送一位,所以對于一個字節(jié)的數(shù)據(jù),至少要分S位才能傳送完畢。串行通信的必要過程是:發(fā)送時,要把并行數(shù)據(jù)變成串行數(shù)據(jù)發(fā)送到線路上去,接收時,要把串行信號再變成并行數(shù)據(jù),這樣才能被計算機及其他設備處理。在串行通信中,收、發(fā)雙方對發(fā)送或接收數(shù)據(jù)的速率要有約定。通過編程可對單片機串行口設定為4種工作方式,其中方式0和方式2的波特率是固定的,而方式1和方式3的波特率是可變的,由定時器T1的溢出率來決定。串行口的4種工作方式對應三種波特率。由于輸入的移位時鐘的來源不同,所以各種方式的波特率計算公式也不一樣,以下是4種方式波特率的計算公式。開發(fā)板的電路圖如下列圖5〕動態(tài)數(shù)碼管顯示數(shù)碼管的顯示原理是靠點亮內部的發(fā)光二極管來發(fā)光,下面就來我們講解一個數(shù)碼管是如何亮起來的。數(shù)碼管內部電路如下列圖所示,從右圖可看出,一位數(shù)碼管的引腳是10個,顯示一個8字需要7個小段,另外還有一個小數(shù)點,所以其內部一共有8個小的發(fā)光二極管,最后還有一個公共端,生產(chǎn)商為了封裝統(tǒng)一,單位數(shù)碼管都封裝10個引腳,其中第3和第8引腳是連接在一起的。而它們的公共端又可分為共陽極和共陰極,中間圖為共陰極內部原理圖,右圖為共陽極內部原理圖。上圖展出了常用的兩種數(shù)碼管的引腳排列和內部構造??偹苤c亮發(fā)光二極管就是要給予它足夠大的正向壓降。所以點亮數(shù)碼管其實也就是給它內部相應的發(fā)光二極管正向壓降。如上圖左〔一共a、b、c、d、e、f、g、DP八段〕,如果要顯示"1〞則要點亮b、c兩段LED;顯示"A〞則點亮a、b、c、e、f、g這六段LED;動態(tài)顯示是多個數(shù)碼管,交替顯示,利用人的視覺暫停作用使人看到多個數(shù)碼管同時顯示的效果。完整程序代碼:主程序文件main.c:-.z.#include"temp.h" //引用temp.h頭文件,包括一些有關溫度傳感器的函數(shù)#include"reg51.h" //引用reg51.h頭文件,說明引腳地址#defineGPIO_DIGP0 //將P0端口定義為GPIO_DIG#defineGPIO_LEDP2 //將P2端口定義為GPIO_LEDsbitLSA=P2^2; //位選,P2^2定義為LSAsbitLSB=P2^3; //同上位選定義變量sbitLSC=P2^4; //同上位選定義變量sbitK3=P3^2; //位選,P3^2定義為K3按鍵unsignedintdisp[8]={0*71,0*71,0*71,0*71,0*71,0*71,0*71,0*71}; //顯示FFFFFFFFunsignedcharcodeDIG_CODE[10]={0*3f,0*06,0*5b,0*4f,0*66,0*6d,0*7d,0*07,0*7f,0*6f};//0、1、2、3、4、5、6、7、8、9的顯示碼unsignedcharcheck1[7]={'0','0','0','0','0','0','0'}; //用來存放串口通信傳送字符unsignedcharcheck2[7]={'G','e','t','T','e','m','p'}; //用來比擬串口通信傳送字符unsignedcharmessage[17]={'4','1','5','0','1','6','0','2',':','0','0','0','0','0','0','0','0'};//顯示**為41501602:unsignedcharDisplayData[8]; //用來存放要顯示的8位數(shù)的值unsignedcharKeyValue=0; //是否按下獨立按鍵的標志位voidDigDisplay(); //動態(tài)數(shù)碼管顯示函數(shù)voidUsartConfiguration(); //串口設置函數(shù)voidLcdDisplay(int); //數(shù)碼管顯示讀取到的溫度voidIntConfiguration(); //設置外部中斷voidDelay(unsignedintn); //延時函數(shù)voidTimer0Configuration(); //定時器初始設置voidCheckMessage(charm); //逐字檢查串口通信字符是否正確unsignedintflag=0; //數(shù)碼管顯示標志位unsignedintj=0; //用于CheckMessage逐字檢查發(fā)送字符unsignedcharNum=0; //動態(tài)數(shù)碼管位選/*******************************************************************************主函數(shù)模塊*******************************************************************************/voidmain() //主函數(shù){ unsignedinti; IntConfiguration(); //初始化外部中斷設置UsartConfiguration(); //初始化串口設置Timer0Configuration(); //初始化定時器設置while(1) { if(flag==1) //當flag為1時數(shù)碼管直接顯示當前溫度 {LcdDisplay(Ds18b20ReadTemp()); //調用溫度傳感器函數(shù)并在數(shù)碼管顯示溫度 }if(flag==0) //當flag為0時數(shù)碼管顯示FFFFFFFF { for(i=0;i<8;i++) //循環(huán)給disp[]數(shù)組賦值 {disp[i]=0*71; //disp[i]賦值 } } }}/*******************************************************************************獨立按鍵模塊*******************************************************************************/voidIntConfiguration() //設置外部中斷{//設置INT0 IT0=1; //跳變沿觸發(fā)方式〔下降沿〕E*0=1; //翻開INT0的中斷允許。//設置INT1 IT1=1; //跳變沿觸發(fā)方式為下降沿E*1=1; //翻開INT1的中斷允許EA=1; //翻開總中斷}voidDelay(unsignedintn)//延時50us誤差0us {unsignedchara,b; for(;n>0;n--) { for(b=1;b>0;b--)for(a=22;a>0;a--); }}voidInt0() interrupt0 //外部中斷0的中斷函數(shù)K3按鍵中斷{ unsignedintk=0; Delay(1); //延時消抖if(K3==0) //如果K3按鍵被按下的話,動態(tài)數(shù)碼管就顯示FFFFFFFF { KeyValue=1; flag=0; for(k=0;k<17;k++) //逐字將message[]字符數(shù)組中字符送入SBUF { SBUF=message[k]; //將接收到的數(shù)據(jù)放入到發(fā)送存放器while(!TI); //等待發(fā)送數(shù)據(jù)完成TI=0; //去除發(fā)送完成標志位 }if(k==17) //如果message數(shù)組發(fā)送完畢就歸零準備下一次 {k=0; } } else KeyValue=0; //K3按鍵沒被按下的時候就一直保持當前狀態(tài),顯示當前溫度}/*******************************************************************************串口通信模塊*******************************************************************************/voidUsartConfiguration() //串口設置{SCON=0*50; //設置為工作方式1 TMOD=0*20; //設置計數(shù)器工作方式2,也就是自動重裝模式PCON=0*80; //波特率加倍TH1=0*F3; //計數(shù)器初始值設置,注意波特率是4800的TL1=0*F3; ES=1; //翻開接收中斷EA=1; //翻開總中斷TR1=1; //翻開計數(shù)器}voidUsart()interrupt4 //串口中斷{unsignedcharreceiveData; receiveData=SBUF; //出去接收到的數(shù)據(jù)RI=0; //去除接收中斷標志位CheckMessage(receiveData); //判斷發(fā)送字節(jié)是否正確}voidCheckMessage(charm) //逐字檢查串口通信字符是否正確{check1[j]=m; //將串口接收到的字符一位一位的賦給check1[] if(check1[j]!=check2[j]) //按位逐字檢查發(fā)送字符是否符合要求{ flag=-1; //不符合直接退出} if(j==6) //符合時改變顯示標志位,數(shù)碼管顯示當前溫度{ flag=1; } j++; //按位檢查}/*******************************************************************************動態(tài)數(shù)碼管模塊*******************************************************************************/voidDigDisplay()interrupt1 //動態(tài)數(shù)碼管顯示{//定時器在工作方式二會自動重裝初,所以不用在賦值。TH0=0*9c; //給定時器賦初值,定時1ms TL0=0*00; GPIO_DIG=0; //消隱switch(Num) //位選,選擇點亮的數(shù)碼管, {case(7): LSA=0;LSB=0;LSC=0;break;//顯示第7位case(6): LSA=1;LSB=0;LSC=0;break;//顯示第6位case(5): LSA=0;LSB=1;LSC=0;break;//顯示第5位case(4): LSA=1;LSB=1;LSC=0;break;//顯示第4位case(3): LSA=0;LSB=0;LSC=1;break;//顯示第3位case(2): LSA=1;LSB=0;LSC=1;break;//顯示第2位case(1): LSA=0;LSB=1;LSC=1;break;//顯示第1位case(0): LSA=1;LSB=1;LSC=1;break;//顯示第0位 }GPIO_DIG=disp[Num]; //發(fā)送段碼Num++; //動態(tài)數(shù)碼管從0到7循環(huán)點亮if(Num>7) Num=0;}voidTimer0Configuration() //定時器初始設置{TMOD=0*20; //選擇為定時器模式,工作方式2,僅用TR*翻開啟動。TH0=0*9C; //給定時器賦初值,定時100us TL0=0*9C; ET0=1; //翻開定時器0中斷允許EA=1; //翻開總中斷TR0=1; //翻開定時器}/*******************************************************************************溫度傳感器DS18B20模塊*******************************************************************************/voidLcdDisplay(inttemp) //數(shù)碼管顯示讀取到的溫度{ unsignedchardatas[]={0,0,0,0,0};//定義數(shù)組floattp; if(temp<0) //當溫度值為負數(shù) { disp[2]=0*40; //如果溫度值為負數(shù)的時候,disp[2]數(shù)碼管顯示負號- //因為讀取的溫度是實際溫度的補碼,所以減1,再取反求出原碼temp=temp-1; temp=~temp; tp=temp; temp=tp*0.0625*100+0.5; //留兩個小數(shù)點就*100,+0.5是四舍五入,因為C語言浮點數(shù)轉換為整型的時候把小數(shù)點//后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就//算由".5,還是在小數(shù)點后面。 } else { disp[2]=0; //如果溫度不是負數(shù),就置零tp=temp;//因為數(shù)據(jù)處理有小數(shù)點所以將溫度賦給一個浮點型變量//如果溫度是正的則,則正數(shù)的原碼就是補碼它本身temp=tp*0.0625*100+0.5; //留兩個小數(shù)點就*100,+0.5是四舍五入,因為C語言浮點數(shù)轉換為整型的時候把小數(shù)點//后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就//算加上0.5,還是在小數(shù)點后面。 }message[9]=(temp/10000)+'0'; //具體溫度的百位message[10]=(temp%10000/1000)+'0'; //具體溫度的十位message[11]=(temp%1000/100)+'0'; //具體溫度的個位message[12]='.'; //小數(shù)點字符message[13]=(temp%100/10)+'0'; //具體溫度的十分位message[14]=(temp%10)+'0'; //具體溫度的千分位message[15]='o'; //message[15]和[16]字符串代表°C攝氏度符號message[16]='C';disp[0]=0; //disp[0]和disp[1]直接置零disp[1]=0;disp[3]=DIG_CODE[temp/10000]; //數(shù)碼管顯示具體溫度的百位disp[4]=DIG_CODE[temp%10000/1000]; //數(shù)碼管顯示具體溫度的十位disp[5]=DIG_CODE[temp%1000/100]|0*80; //數(shù)碼管顯示具體溫度的個位//共陰接法,數(shù)碼管為高電平驅動,且小數(shù)點的段接在IO的bit7,所以用|0*80來點亮小數(shù)點disp[6]=DIG_CODE[temp%100/10]; //數(shù)碼管顯示具體溫度的十分位disp[7]=DIG_CODE[temp%10]; //數(shù)碼管顯示具體溫度的千分位}-.z.溫度傳感器temp.c:-.z.#include"temp.h"/********************************************************************************函數(shù)名:Delay1ms*函數(shù)功能:延時函數(shù)*輸入:無*輸出 :無*******************************************************************************/voidDelay1ms(unsignedinty){ unsignedint*; for(y;y>0;y--) for(*=110;*>0;*--);}/********************************************************************************函數(shù)名:Ds18b20Init*函數(shù)功能:初始化*輸入:無*輸出 :初始化成功返回1,失敗返回0*******************************************************************************/unsignedcharDs18b20Init(){ unsignedinti; DSPORT=0; //將總線拉低480us~960us i=70; while(i--);//延時642us DSPORT=1; //然后拉高總線,如果DS18B20做出反響會將在15us~60us后總線拉低i=0; while(DSPORT) //等待DS18B20拉低總線 {i++; if(i>5000)//等待>5MS return0;//初始化失敗 }return1;//初始化成功}/********************************************************************************函數(shù)名:Ds18b20WriteByte*函數(shù)功能:向18B20寫入一個字節(jié)*輸入:*輸出 :無*******************************************************************************/voidDs18b20WriteByte(unsignedchardat){ unsignedinti,j; for(j=0;j<8;j++) { DSPORT=0; //每寫入一位數(shù)據(jù)之前先把總線拉低1us i++; DSPORT=dat&0*01;//然后寫入一個數(shù)據(jù),從最低位開場i=6; while(i--);//延時68us,持續(xù)時間最少60us DSPORT=1; //然后釋放總線,至少1us給總線恢復時間才能接著寫入第二個數(shù)值dat>>=1; }}/********************************************************************************函數(shù)名:Ds18b20ReadByte*函數(shù)功能:讀取一個字節(jié)*輸入:*輸出 :無*******************************************************************************/unsignedcharDs18b20ReadByte(){ unsignedcharbyte,bi; unsignedinti,j; for(j=8;j>0;j--) { DSPORT=0;//先將總線拉低1us i++; DSPORT=1;//然后釋放總線i++; i++;//延時6us等待數(shù)據(jù)穩(wěn)定bi=DSPORT; //讀取數(shù)據(jù),從最低位開場讀取/*將byte左移一位,然后與上右移7位后的bi,注意移動之后移掉那位補0。*/ byte=(byte>>1)|(bi<<7); i=4; //讀取完之后等待48us再接著讀取下一個數(shù)while(i--); } returnbyte;}/********************************************************************************函數(shù)名:Ds18b20ChangTemp*函數(shù)功能:讓18b20開場轉換溫度*輸入:*輸出 :無*******************************************************************************/voidDs18b20ChangTemp(){ Ds18b20Init(); Delay1ms(1); Ds18b20Writ
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 聯(lián)盟建設促進保安工作的整合計劃
- 社區(qū)環(huán)境保護從我做起計劃
- 發(fā)現(xiàn)自然之美-生物多樣性保護
- 高密合伙創(chuàng)業(yè)協(xié)議書范文范本
- 企業(yè)承包合同協(xié)議書范文范本下載
- 變壓器油轉讓協(xié)議書范文模板
- 建設工程質量管理辦法全文
- 教培合作簡單協(xié)議書
- 2023-2024學年四川省綿陽市三臺中學高三3月月考數(shù)學試題文試卷
- 品德與社會一年級課件
- 電氣工程及其自動化職業(yè)規(guī)劃課件
- GB/T 19228.1-2024不銹鋼卡壓式管件組件第1部分:卡壓式管件
- 第四單元基礎測試卷-2024-2025學年統(tǒng)編版語文六年級上冊
- 2024年房產(chǎn)贈與合同范本(31篇)
- 2024年中國移動校園招聘高頻難、易錯點500題模擬試題附帶答案詳解
- 物理透鏡 課件 2024-2025學年蘇科版八年級上冊物理
- 單位消防安全管理制度
- 地理氣溫的變化與分布課件-2024-2025學年七年級地理上學期(2024)人教版
- 【智慧醫(yī)療】醫(yī)療健康產(chǎn)業(yè)園概念策劃方案(XQ)
- 智能分揀與配送中心建設方案
- 2024年計算機二級WPS考試題庫380題(含答案)
評論
0/150
提交評論