51單片機超聲波測距離帶溫度補償_第1頁
51單片機超聲波測距離帶溫度補償_第2頁
51單片機超聲波測距離帶溫度補償_第3頁
51單片機超聲波測距離帶溫度補償_第4頁
51單片機超聲波測距離帶溫度補償_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、超聲波模塊原理圖: 發(fā)射 接收原理圖PCB:51單片機原理圖:軟件部分C語言程序:/*= 調(diào)試要求: 1.MCU:AT89S52芯片或AT89C52 2.晶振:12MHz 調(diào)試注意: 本程序帶溫度補償,采用DS18B20測量溫度 1.LCD1602液晶屏有顯示后,才接入超聲波模塊。 2.注意超聲波模塊電源的極性。不清楚請參好淘寶的電路圖 3.沒有選用頻率為12MHz晶振,用了別的頻率晶振,單片機定時器的測量值與 發(fā)出的40KHz頻率脈沖不對。 4.使用者經(jīng)常誤發(fā)出20KHZ脈沖當40KHZ脈沖。(40KHz頻率脈沖,周期25us, 占空比為50% = 12.5us) 5.如果是用開發(fā)板調(diào)超聲波

2、模塊,請檢查開發(fā)板上的電路是否與超聲波模塊的 控制腳復用了, 若復用了,請通過跳線分開發(fā)板上的電路。 6如果使用的是萬用板,請確定單片機的復位電路和晶振電路是否正常,同時 單片機的31腳(EA)記得 接高電平。=*/#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int/=LCD1602接口定義=/*- |DB0-P2.0 | DB4-P2.4 | RW-P0.1 | |DB1-P2.1 | DB5-P2.5 | RS-P0.2 | |DB2-P

3、2.2 | DB6-P2.6 | E-P0.0 | |DB3-P2.3 | DB7-P2.7 | 注意,P0.0到P0.2需要接上拉電阻 -=*/#define LCM_Data P2 /數(shù)據(jù)接口#define Busy 0x80 /用于檢測LCM狀態(tài)字中的Busy標識sbit LCM_RW = P01; /讀寫控制輸入端,LCD1602的第五腳sbit LCM_RS = P02; /寄存器選擇輸入端,LCD1602的第四腳sbit LCM_E = P00; /使能信號輸入端,LCD1602的第6腳/=超聲波模塊定義=sbit RemPin = P32;/ 接收端(這個不能修改,因為是外部中斷

4、(INT0)的引腳)sbit TxPin = P31;/ 發(fā)射端 /*/ds18b20數(shù)字溫度傳感器控制引腳定義 sbit dq_ds18b20=P33;/定義控制DS18B20/*/LCD顯示模塊的函數(shù)聲明void WriteDataLCM(uchar WDLCM);/LCD模塊寫數(shù)據(jù)void WriteCommandLCM(uchar WCLCM,BuysC); /LCD模塊寫指令uchar ReadDataLCM(void);/LCD模塊讀數(shù)據(jù)uchar ReadStatusLCM(void);/讀LCD模塊的忙標void DisplayOneChar (uchar X,uchar Y,

5、uchar ASCII);/在第X+1行的第Y+1位置顯示一個字符void DisplayListChar (uchar X,uchar Y,uchar delayms,uchar code *DData);void DisplayCursorPos (uchar X, uchar Y);void LCMInit (void);void DisplayIntData (uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu);void DisplayCharData (uchar X, uchar Y,uchar ZiFu);/*/延時函

6、數(shù)聲明void delay25us_40KHz(unsigned char us);void DelayUs(uint us);void DelayMs(uint Ms);void delay_3us();/3US的延時程序void delay_8us(unsigned int t);/8US延時基準程序void delay_50us(unsigned int t);/延時50*T微妙函數(shù)的聲明/*/DS18B20測溫函數(shù)定義void w_1byte_ds18b20(uchar value);/向DS18B20寫一個字節(jié) uchar r_1byte_ds18b20(void);/從DS18B2

7、0讀取一個字節(jié)的數(shù)據(jù)void rest_ds18b20(void);/DS18B20復位程序void readtemp_ds18b20(void);/讀取溫度 void display_temp(void);/溫度顯示程序/*/參數(shù)定義uint length = 0; / 測距的長度0.00Muchar flag = 0; / 測距的標志有信號接收=1uchar templ,temph;uint speed;/根據(jù)溫度計算出來的聲音速度uchar t_b,t_s,t_g,t_x;/從左到右分別存儲溫度百位,十位,個位,小數(shù)位uchar flag1;/溫度正負性暫存,1為正數(shù),0為負數(shù)const

8、 unsigned char tabl3=0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09; /*= 主程序=*/void main(void) uchar i; LCMInit(); /1602初始化 EX0 = 1; /允許總中斷中斷,使能 INT0 外部中斷 ET0 = 1; TMOD=0x11; /設定T0為16位時器,設定T1為16位時器 DisplayOneChar( 0,14,'m'); DisplayListChar(0,0,0, "Dista

9、nc: "); /顯示字符串 while(1) readtemp_ds18b20(); display_temp();/顯示溫度 for(i=0;i<20;i+) DisplayIntData(0, 13,length,5,3);/顯示測量距離 TH0=0x00; TL0=0x00; TR0=1; /啟動定時器0 EA = 1; /允許所有中斷 delay25us_40KHz(15); /發(fā)出脈沖信號 DelayMs(200); /*/溫度顯示函數(shù)void display_temp() if(flag1=1)/溫度為正數(shù)時的顯示程序 DisplayOneChar( 1,2,&#

10、39;+'); else DisplayOneChar( 1,2,'-'); /顯示溫度信息 DisplayOneChar( 1,0,'T'); DisplayOneChar( 1,1,':'); DisplayOneChar( 1,3,t_s+0x30); DisplayOneChar( 1,4,t_g+0x30); DisplayOneChar( 1,5,'.'); DisplayOneChar( 1,6,t_x+0x30); /顯示速度信息 DisplayOneChar( 1,8,'S'); Disp

11、layOneChar( 1,9,':'); DisplayOneChar( 1,10,speed/100%10+0x30); DisplayOneChar( 1,11,speed/10%10+0x30); DisplayOneChar( 1,12,speed%10+0x30); DisplayOneChar( 1,13,'M'); DisplayOneChar( 1,14,'/'); DisplayOneChar( 1,15,'S');/*/讀取溫度 void readtemp_ds18b20(void) uchar temp32

12、; rest_ds18b20(); w_1byte_ds18b20(0xcc); /跳過讀序列號的操作 w_1byte_ds18b20(0x44); /啟動溫度轉(zhuǎn)換 delay_8us(2); rest_ds18b20(); w_1byte_ds18b20(0xcc); /跳過讀序列號的操作 w_1byte_ds18b20(0xbe); /讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度 templ=r_1byte_ds18b20(); temph=r_1byte_ds18b20(); if(temph&0xf0)/判斷溫度的正負性 flag1=0; temph=-temph; t

13、empl=-templ; t_x=tabl3templ & 0x0f;/計算溫度的小數(shù) temp32=temph & 0x0f; temp32<<=4; templ>>=4; temp32=temp32 | templ; t_b=temp32/100%10;/計算溫度的百位數(shù)據(jù) t_s=temp32/10%10;/計算溫度的十位數(shù)據(jù) t_g=temp32%10;/計算溫度的個位數(shù)據(jù) speed=331.4-0.607*(temp32 | templ); else/為正數(shù) t_x=tabl3templ & 0x0f;/計算溫度的小數(shù) temp32=

14、temph & 0x0f; temp32<<=4; templ>>=4; temp32=temp32 | templ; t_b=temp32/100%10;/計算溫度的百位數(shù)據(jù) t_s=temp32/10%10;/計算溫度的十位數(shù)據(jù) t_g=temp32%10;/計算溫度的個位數(shù)據(jù) flag1=1; speed=311.4+0.607*(temp32 | templ); /*= 功 能: 在1602顯示一個整數(shù)數(shù)據(jù) 說 明: 顯示一個整數(shù)數(shù)據(jù)-9999->32625. 從右至左顯示數(shù)據(jù)5位: =*/void DisplayIntData(uchar X,

15、uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu) uchar i=0,k=0, BCD5=0; if(Digit>5) Digit=5; if(ZhengShu<0) k=1;/負數(shù)示志位 ZhengShu=-ZhengShu; BCD4 = ZhengShu / 10000; /求出萬位數(shù)據(jù) ZhengShu = ZhengShu % 10000; BCD3 = ZhengShu / 1000; /求出千位數(shù)據(jù) ZhengShu = ZhengShu % 1000; BCD2 = ZhengShu / 100; /求出百位數(shù)據(jù) Zhe

16、ngShu = ZhengShu % 100; BCD1 = ZhengShu / 10; /求出十位數(shù)據(jù) BCD0 = ZhengShu % 10; /求出個位數(shù)據(jù) for(i=0;i<Digit;i+)/輸出顯示的數(shù)值 if(i=XiaoShu)&&(0!=XiaoShu) DisplayOneChar(X,Y-i,'.');/輸出小數(shù)點 Y= Y-1; DisplayOneChar(X,Y-i,BCDi+0x30); /顯示一個字符 if(k=1) DisplayOneChar(X,Y-1,'-');/輸出負符/*/讀一個字節(jié) uch

17、ar r_1byte_ds18b20(void) uchar i=0; uchar value = 0; for (i=0;i<8;i+) value>>=1; dq_ds18b20=0;/ DQ_L; delay_3us(); dq_ds18b20=1; /DQ_H; delay_8us(2); if(dq_ds18b20=1) value|=0x80; delay_8us(6); /延時40us dq_ds18b20=1; return value;/*/子程序功能:向DS18B20寫一字節(jié)的數(shù)據(jù)void w_1byte_ds18b20(uchar value) ucha

18、r i=0; for(i=0;i<8;i+) dq_ds18b20=1; delay_3us(); dq_ds18b20=0; delay_8us(2); if (value & 0x01) dq_ds18b20=1; /DQ = 1 delay_50us(1); /延時50us 以上 delay_8us(2); value>>=1; dq_ds18b20=1; /DQ = 1/;*/ds18b20復位子程序void rest_ds18b20(void) rest:delay_3us(); /稍做延時 delay_3us(); dq_ds18b20=1; delay_

19、3us(); dq_ds18b20=0;/ DQ_L; delay_50us(11);/480us<T<960us dq_ds18b20=1;/拉高總線 delay_8us(5); if(dq_ds18b20=1) return; delay_50us(2); /延時90us if(dq_ds18b20=1) return; else goto rest; /=超聲波模塊測試子程序=/*= 注意:是用12MHz晶振 設定延時時間:x*25us 與 產(chǎn)生40KHZ的脈沖=*/void delay25us_40KHz(unsigned char us) while(us-) TxPin

20、 = 0; _nop_();_nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_(); TxPin = 1; _nop_();_nop_(); _nop_();_nop_();TxPin = 1;/*= 中斷程序的入口 (注意:接收與發(fā)射的電平是相反的)=*/void init0int() interrupt 0 uint timer_us = 0;TR0=0; /關(guān)閉定時器0timer_us = TH0*256+TL0;if(timer_us>190)timer_us=tim

21、er_us-180;/修正測距的距離 if(timer_us<=735) timer_us=timer_us-96;/二次修正 if(timer_us>5059) timer_us+=29; if(timer_us>5470) timer_us+=29; if(timer_us>6410) timer_us+=29; if(timer_us>7410) timer_us+=29; if(timer_us>8410) timer_us+=29; if(timer_us>9410) timer_us+=29; if(timer_us>10410) t

22、imer_us+=29; length = (unsigned long)(speed)*timer_us)/2000;/計算長度,是擴大100倍flag = 0;EA = 0; /禁止所有中斷/*= 功 能:在1602顯示一個字符數(shù)據(jù) 說 明:顯示一個字符數(shù)據(jù)0256. 從左至右顯示數(shù)據(jù)3位=*/void DisplayCharData(uchar X, uchar Y,uchar ZiFu) uchar i=0; uchar ValueBCD3; ValueBCD0 = ZiFu / 100; /求出百位數(shù)據(jù) ZiFu = ZiFu % 100; ValueBCD1 = ZiFu / 10

23、; /求出十位數(shù)據(jù) ValueBCD2 = ZiFu % 10; /求出個位數(shù)據(jù) for(i=0;i<3;i+)/輸出顯示的數(shù)值 DisplayOneChar(X,Y+i,ValueBCDi+0x30); /顯示一個字符 /*= 超出測量時間=*/void timer0int (void) interrupt 1 TR0=0; /關(guān)閉定時器0length = 0; /超出測量時間顯示示0 flag = 1; /EA = 0; /禁止所有中斷 /*= LCM初始化=*/void LCMInit(void) LCM_Data = 0; WriteCommandLCM(0x38,0); /三次

24、顯示模式設置,不檢測忙信號 DelayMs(5); WriteCommandLCM(0x38,0); DelayMs(5); WriteCommandLCM(0x38,0); DelayMs(5); WriteCommandLCM(0x38,1); /顯示模式設置,開始要求每次檢測忙信號 WriteCommandLCM(0x08,1); /關(guān)閉顯示 WriteCommandLCM(0x01,1); /顯示清屏 WriteCommandLCM(0x06,1); / 顯示光標移動設置 WriteCommandLCM(0x0C,1); / 顯示開及光標設置 DelayMs(100);/*= 顯示光標

25、的位置=*/void DisplayCursorPos( unsigned char X, unsigned char Y) X &= 0x1; Y &= 0xF; /限制Y不能大于15,X不能大于1 if (X) Y |= 0x40; /當要顯示第二行時地址碼+0x40; Y |= 0x80; / 算出指令碼 WriteCommandLCM(Y, 1); /這里不檢測忙信號,發(fā)送地址碼/*= 按指定位置顯示一串字符:第 X 行,第 y列 注意:字符串不能長于16個字符=*/void DisplayListChar(uchar X,uchar Y,uchar delayms,

26、uchar code *DData) unsigned char ListLength; ListLength = 0; X &= 0x1; Y &= 0xF; /限制X不能大于15,Y不能大于1 while (DDataListLength!='0') /若到達字串尾則退出 if (Y <= 0xF) /X坐標應小于0xF DisplayOneChar(X, Y, DDataListLength); /顯示單個字符 ListLength+; Y+; DelayMs(delayms);/延時顯示字符串 else break;/跳出循環(huán)體 /*= 設定延時時

27、間:x*1us=*/void DelayUs(uint us) while(us-); /*= 設定延時時間:x*1ms=*/void DelayMs(uint Ms) uint i,TempCyc; for(i=0;i<Ms;i+) TempCyc = 250; while(TempCyc-); /=LCD1602顯示子程序= /*= 寫數(shù)據(jù)函數(shù): E =高脈沖 RS=1 RW=0=*/void WriteDataLCM(unsigned char WDLCM) ReadStatusLCM(); /檢測忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0; LCM_E = 0; /若晶振速度太高可以在這后加小的延時 LCM_E = 0; /延時 LCM_E = 1;/*= 寫指令函數(shù): E=高脈沖 RS=0 RW=0=*/void WriteCommandLCM(unsigned char WCLCM,BuysC) /BuysC為0時忽略忙檢測 if (BuysC) ReadStatusLCM(); /根據(jù)需要檢測忙 LCM_Data = WCLC

溫馨提示

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

評論

0/150

提交評論