1. 程式人生 > >HY-SRF05超聲波測距

HY-SRF05超聲波測距

1. 模組(OUT腳不知有什麼用)

這裡寫圖片描述

2. 工作原理

這裡寫圖片描述

3. 時序圖

這裡寫圖片描述

4. 計算公式

這裡寫圖片描述

5. 51測試原始碼,串列埠顯示

/**********************************************************************************
* 功能:HY-SRF05超聲波測距模組測試,通過串列埠列印
* 處理器:STC89C52RC
* 晶振:11.0592
* 編譯環境:Keil uVision4
* 時間:2015-12-10
* 作者:ly
* 備註:Trig  ---  P1_0
*       Echo  ---  外部中斷0(P3_2)
*       OUT   ---  
*       Vcc   ---  VCC
*       GND   ---  GND
**********************************************************************************/
#include <reg52.h> #include <stdio.h> //sprintf #include <string.h> //strlen #include <intrins.h> //_nop_ #define uint unsigned int #define uchar unsigned char sbit TX = P3^1; sbit Trig = P1^0; int time; //計算迴響訊號脈衝寬度 /****************************** 初始化函式 *****************************************/
//外部中斷0初始化(P3_2) void int0_init(void) { IE0 = 0; //外部中斷0標誌位清0 IT0 = 1; //外部中斷0下降沿觸發 EX0 = 1; //外部中斷0允許 } //定時器0初始化 void time0_init(void) { TMOD |= 0x09; //0000 1001: GATE門控開,只有 TRx==1 && INTx==1 才可啟動T0,T0定時方式1(16位) TH0 = 0; TL0 = 0; TF0 = 0; //T0標誌位清0 ET0 = 1; //T0中斷允許 TR0 = 1; //T0工作允許
} //串列埠初始化 void uart_init(void) { SCON = 0x40; //0100 0000:序列方式1 TMOD |= 0x20; //T1定時方式2(8位自動裝入) TH1 = 0xFD; TL1 = 0xFD; //波特率:9600 ES = 0; //串列埠中斷禁止 TR1 = 1; //T1啟動 } void init(void) { EA = 0; //總中斷禁止 Trig = 0; uart_init(); time0_init(); int0_init(); EA = 1; //總中斷允許 } /************************************************************************************/ void delay15us(void) { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } void delay15ms(void) { int i; for (i = 0; i < 1000; i++) delay15us(); } void uart_send_char(uchar ch) //串列埠傳送一個Byte { SBUF = ch; while (!TI); TI = 0; } void uart_send_string(uchar str[], uint len) //串列埠傳送字串 { int i; for (i = 0; i < len; i++) uart_send_char(str[i]); } /* 主函式 */ void main(void) { int i; float distance; //距離 uchar display[20]; //串列埠顯示距離 init(); while (1) { //建議測量週期60ms以上,以防止發射訊號對迴響訊號的影響 for (i = 0; i < 4; i++) delay15ms(); //傳送觸發訊號(10us以上TTL脈衝),如果檢測到迴響,Echo(P3^2)將拉高,則T0開始計時 Trig = 1; delay15us(); Trig = 0; //等待Echo(P3^2)下降沿到來(迴響訊號脈衝)觸發外部中斷 time = 0; i = 0; while (time==0 && i<=65536) //直到time被中斷計算出時間或者被標記計時溢位或者i超時 i++; //防止死迴圈 if (i > 65536) //一直監測不到迴響,Echo(P3^2)沒有拉高,超時 { uart_send_string("time out", 8); uart_send_char(0x0A); //換行/新行 uart_send_char(0x0D); //回車 continue; } if (time == -1) //計時溢位 { uart_send_string("T0 overflow", 11); uart_send_char(0x0A); //換行/新行 uart_send_char(0x0D); //回車 } else { distance = time / 58.0; //公式:uS / 58 = 釐米 sprintf(display, "%f CM", distance); uart_send_string(display, strlen(display)); uart_send_char(0x0A); //換行/新行 uart_send_char(0x0D); //回車 } } } /*************************** 中斷處理 ******************************/ // 外部中斷0處理 void int0() interrupt 0 { EA = 0; //總中斷禁止 time = TH0 * 256 + TL0; //迴響時間 TH0 = 0; TL0 = 0; EA = 1; //總中斷允許 } // 定時器0中斷處理 void time0() interrupt 1 { //進入到這裡,說明計時溢位 EA = 0; //總中斷禁止 TH0 = 0; TL0 = 0; time = -1; EA = 1; //總中斷允許 } /********************************************************************/

6. 結果(串列埠助手之類軟體)

這裡寫圖片描述