標(biāo)題:
單片機(jī)超聲波測距不到一米,超出50厘米就不準(zhǔn)了,附源碼
[打印本頁]
作者:
1021550891
時(shí)間:
2018-4-26 15:58
標(biāo)題:
單片機(jī)超聲波測距不到一米,超出50厘米就不準(zhǔn)了,附源碼
超聲波測距不到一米,超出50厘米就不準(zhǔn)了
主程序
#include "Ultrasonic.h"
/*軟件延時(shí),延時(shí)時(shí)間(t*10)us*/
void DelayX10us(unsigned char t)
{
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
/* 獲取測量數(shù)據(jù),返回值:以毫米位單位的距離值 */
unsigned int GetDistance()
{
float time;
float result;
TH1 = 0; //定時(shí)器1清零,準(zhǔn)備本次測距計(jì)數(shù)
TL1 = 0;
Trig = 1; //Trig輸出高電平
DelayX10us(2); //延時(shí)20us
Trig = 0; //Trig輸出低電平,至此產(chǎn)生一個20us的脈沖信號以啟動超聲波模塊
while(!Echo); //等待回波信號,回波信號自動使能T1計(jì)數(shù)
while(Echo); //等待回波信號結(jié)束,T1同時(shí)自動停止
if (TF1 == 1) //TF1為1時(shí)說明定時(shí)器溢出了
{
TF1 = 0; //清除標(biāo)志位
time = 65535; //溢出時(shí),直接設(shè)置為最大計(jì)數(shù)值
}
else
{
time = TH1*256 + TL1; //未溢出時(shí),讀取其實(shí)際計(jì)數(shù)值
}
time = time * (12/11.0592) / 2; //將計(jì)數(shù)周期轉(zhuǎn)換為實(shí)際時(shí)間(us);超聲波測得的是來回距離,需要除以2得到單程距離所對應(yīng)的時(shí)間
result = (time/1000000) * 340; // time(s)*速度 = 距離 ,340為聲波在空氣中的傳播速度(m/s)
if (result > 4.0) //判斷是否超出模塊的測量范圍
{
result = 4.0; //超出上限4m則設(shè)置為4m
}
else if (result < 0.02)
{
result = 0.02; //低于下限0.02m則設(shè)置為0.02m
}
return (unsigned int)(result*1000); //以無符號整形數(shù)返回測量結(jié)果,乘1000使其單位變?yōu)楹撩?br />
}
/*初始化超聲波模塊*/
void InitUltrasonic()
{
TMOD &= 0x0f;
TMOD |= 0x90; //設(shè)置T1為方式1,GATE=1啟用門控模式;
TH1 = 0;
TL1 = 0;
ET1 = 0; //關(guān)閉T0中斷
TR1 = 1; //使能定時(shí)器,由于使用GATE位控制定時(shí)器啟停,所以定時(shí)器必須打開,啟停將由外部信號觸發(fā) 詳情參考 <手把手將你學(xué)51單片機(jī)> P59
Trig = 0; //拉低模塊觸發(fā)引腳
}
#define _LCD1602_C
#include "Lcd1602.h"
/* 等待液晶準(zhǔn)備好 */
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; //讀取狀態(tài)字
LCD1602_E = 0;
} while (sta & 0x80); //bit7等于1表示液晶正忙,重復(fù)檢測直到其等于0為止
}
/* 向LCD1602液晶寫入一字節(jié)命令,cmd-待寫入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 向LCD1602液晶寫入一字節(jié)數(shù)據(jù),dat-待寫入數(shù)據(jù)值 */
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 設(shè)置顯示RAM起始地址,亦即光標(biāo)位置,(x,y)-對應(yīng)屏幕上的字符坐標(biāo) */
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if (y == 0) //由輸入的屏幕坐標(biāo)計(jì)算顯示RAM的地址
{
addr = 0x00 + x; //第一行字符地址從0x00起始
}
else
{
addr = 0x40 + x; //第二行字符地址從0x40起始
}
LcdWriteCmd(addr | 0x80); //設(shè)置RAM地址
}
/* 在液晶上顯示字符串,(x,y)-對應(yīng)屏幕上的起始坐標(biāo),str-字符串指針 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
LcdSetCursor(x, y); //設(shè)置起始地址
while (*str != '\0') //連續(xù)寫入字符串?dāng)?shù)據(jù),直到檢測到結(jié)束符
{
LcdWriteDat(*str++);
}
}
/* 初始化1602液晶 */
void InitLcd1602()
{
LcdWriteCmd(0x38); //16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
LcdWriteCmd(0x0C); //顯示器開,光標(biāo)關(guān)閉
LcdWriteCmd(0x06); //文字不動,地址自動+1
LcdWriteCmd(0x01); //清屏
}
#include "Ultrasonic.h"
/*軟件延時(shí),延時(shí)時(shí)間(t*10)us*/
void DelayX10us(unsigned char t)
{
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
/* 獲取測量數(shù)據(jù),返回值:以毫米位單位的距離值 */
unsigned int GetDistance()
{
float time;
float result;
TH1 = 0; //定時(shí)器1清零,準(zhǔn)備本次測距計(jì)數(shù)
TL1 = 0;
Trig = 1; //Trig輸出高電平
DelayX10us(2); //延時(shí)20us
Trig = 0; //Trig輸出低電平,至此產(chǎn)生一個20us的脈沖信號以啟動超聲波模塊
while(!Echo); //等待回波信號,回波信號自動使能T1計(jì)數(shù)
while(Echo); //等待回波信號結(jié)束,T1同時(shí)自動停止
if (TF1 == 1) //TF1為1時(shí)說明定時(shí)器溢出了
{
TF1 = 0; //清除標(biāo)志位
time = 65535; //溢出時(shí),直接設(shè)置為最大計(jì)數(shù)值
}
else
{
time = TH1*256 + TL1; //未溢出時(shí),讀取其實(shí)際計(jì)數(shù)值
}
time = time * (12/11.0592) / 2; //將計(jì)數(shù)周期轉(zhuǎn)換為實(shí)際時(shí)間(us);超聲波測得的是來回距離,需要除以2得到單程距離所對應(yīng)的時(shí)間
result = (time/1000000) * 340; // time(s)*速度 = 距離 ,340為聲波在空氣中的傳播速度(m/s)
if (result > 4.0) //判斷是否超出模塊的測量范圍
{
result = 4.0; //超出上限4m則設(shè)置為4m
}
else if (result < 0.02)
{
result = 0.02; //低于下限0.02m則設(shè)置為0.02m
}
return (unsigned int)(result*1000); //以無符號整形數(shù)返回測量結(jié)果,乘1000使其單位變?yōu)楹撩?br />
}
/*初始化超聲波模塊*/
void InitUltrasonic()
{
TMOD &= 0x0f;
TMOD |= 0x90; //設(shè)置T1為方式1,GATE=1啟用門控模式;
TH1 = 0;
TL1 = 0;
ET1 = 0; //關(guān)閉T0中斷
TR1 = 1; //使能定時(shí)器,由于使用GATE位控制定時(shí)器啟停,所以定時(shí)器必須打開,啟停將由外部信號觸發(fā) 詳情參考 <手把手將你學(xué)51單片機(jī)> P59
Trig = 0; //拉低模塊觸發(fā)引腳
}
復(fù)制代碼
作者:
wulin
時(shí)間:
2018-4-26 20:57
這種低成本玩藝本來就是練練手的,別指望有多完美。要想性能好就買工業(yè)級的產(chǎn)品。
作者:
zl2168
時(shí)間:
2018-4-26 22:41
不是因?yàn)椤暗统杀就嫠嚒保浅绦蛴袉栴}。
作者:
zzzy
時(shí)間:
2018-4-26 23:50
沒猜錯的話,超過50厘米是因?yàn)槎〞r(shí)器溢出了,建議你用雙定時(shí)器,開始測量然后到收到回波,通過比較器得到精確計(jì)數(shù),然后得到時(shí)間來算距離。
作者:
1021550891
時(shí)間:
2018-4-28 12:10
zzzy 發(fā)表于 2018-4-26 23:50
沒猜錯的話,超過50厘米是因?yàn)槎〞r(shí)器溢出了,建議你用雙定時(shí)器,開始測量然后到收到回波,通過比較器得到精 ...
能不能說的再清楚點(diǎn)
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1