一、設計目標
? ? 使用51單片機和超聲波測距模塊實現(xiàn)超聲波測距。
二、主要功能
? ? 超聲波測距。
三、硬件部分
? ? 51單片機,超聲波測距模塊,導線,動態(tài)數(shù)碼管,74HC245芯片,74HC138芯片。
圖1 ?????????????????????
圖2
?文章來源地址http://www.zghlxwxcb.cn/news/detail-489124.html
圖3
?文章來源:http://www.zghlxwxcb.cn/news/detail-489124.html
圖4
? ? 圖1為超聲波測距模塊的內部電路圖。
? ? 圖2為超聲波測距的輸出和接收聲波的時序邏輯圖。
? ? 圖3、圖4為動態(tài)數(shù)碼管的控制。使用51單片機的P0_0、P0_1、P0_2端連接74HC138芯片的A、B、C引腳,從而控制哪一個數(shù)碼管被點亮。
?
四、程序框圖
?
五、代碼說明
? ? 代碼由延時函數(shù)、定時器函數(shù)、算距離函數(shù)、測時間函數(shù)、數(shù)碼管控制函數(shù)、數(shù)碼管顯示結果函數(shù)、主函數(shù)組成
? ? 延時函數(shù)和數(shù)碼管控制函數(shù)配合,負責動態(tài)數(shù)碼管顯示的硬件控制。
? ? 定時器函數(shù)用于測距時定時。
? ? 測時間函數(shù)計算超聲波發(fā)出到接收的時間。
? ? 算距離函數(shù)用于對測量的時間進行計算得出距離。
? ? 數(shù)碼管顯示結果函數(shù)用于對測量出的結果進行顯示。
? ? 數(shù)碼管控制函數(shù)用來控制動態(tài)數(shù)碼管點亮第幾位和顯示的數(shù)字。
1.主函數(shù)
? ? 主函數(shù)對函數(shù)進行調用,首先調用測時間函數(shù)得出超聲波發(fā)出到接收的時間。然后調用算距離函數(shù)將時間轉化為距離(單位:厘米)。最后調用數(shù)碼管顯示結果函數(shù)顯示測量的結果。
/******************************************主函數(shù)***************************************/
void main()
{
unsigned int time = 0;
float distance;
while(1)
{
time = RunOnce();//傳感器接收到高電平的時間
distance = GetDistance(time);
xianshi(distance);
}
}
?
2.子函數(shù)1
? ? 數(shù)碼管控制函數(shù)。使用switch()功能,根據硬件中的表格,提前將點亮每個動態(tài)數(shù)碼管所需的信號定義好。Switch()可以采集輸入動態(tài)數(shù)碼管函數(shù)的值,其中前邊一位是點亮第幾位動態(tài)數(shù)碼管。另外再定義一個數(shù)字數(shù)組,數(shù)組的內容為單個動態(tài)數(shù)碼管顯示0-9即全滅時所需的P3端輸出值。
unsigned char shuzi[]={0x3f/*0*/,0x06/*1*/,0x5b/*2*/,0x4f/*3*/,0x66/*4*/,0x6d/*5*/,0x7d/*6*/,0x07/*7*/,0x7f/*8*/,0x6f/*9*/};//顯示的數(shù)字(num)的數(shù)組
void shumaguan(unsigned char wei,num)//第幾位(wei)顯示
{
switch(wei)
{
case 1:P0_2=0;P0_1=0;P0_0=0;break;
case 2:P0_2=0;P0_1=0;P0_0=1;break;
case 3:P0_2=0;P0_1=1;P0_0=0;break;
case 4:P0_2=0;P0_1=1;P0_0=1;break;
case 5:P0_2=1;P0_1=0;P0_0=0;break;
case 6:P0_2=1;P0_1=0;P0_0=1;break;
case 7:P0_2=1;P0_1=1;P0_0=0;break;
case 8:P0_2=1;P0_1=1;P0_0=1;break;
}
P3=shuzi[num];
delay(1);
}
?
3.子函數(shù)2
? ? 延時函數(shù)。和數(shù)碼管控制函數(shù)配合,負責動態(tài)數(shù)碼管顯示的硬件控制。
/******************************************延時函數(shù)***************************************/
void delay(unsigned int xms)//延時x毫秒
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=112;j>0;j--);
return;
}
?
4.子函數(shù)3
????定時器函數(shù)。因輸出超聲波時需要10us的高電平,因此定義該函數(shù)。同時也可以用于計算發(fā)出到接收的時間。
/**********************************定時器函數(shù) 延時10us*************************************/
void Delay10us()
{
TMOD |= 0x01;//16位定時器/計數(shù)器
TH0 = 0xFF;//賦初值
TL0 = 0xF6;//賦初值
TR0 = 1;//啟動
while(!TF0);//溢出
TF0 = 0;//清溢出
}
?
5.子函數(shù)4
? ? 算距離函數(shù)。用于將測出的時間轉化為距離。
/******************************************算距離函數(shù)***************************************/
float GetDistance(unsigned int time)
{
float distance;
distance = (float)time * 0.017;//cm 距離=高電平時間×聲速/2 0.017cm/us
return distance;//將距離返回主函數(shù)
}
?
6.子函數(shù)5
? ? 測時間函數(shù)。與定時器函數(shù)配合實現(xiàn)超聲波的發(fā)出與時間測量。
/******************************************測時間函數(shù)***************************************/
unsigned int RunOnce()
{
unsigned int time;
/******************發(fā)送10us高電平信號*************/
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
/**************等待高電平信號接收*****************/
while(!Echo);
/*********T0清0重新計數(shù)(高電平持續(xù)時間)*********/
TH0 = 0;
TL0 = 0;
TR0 = 1;
/*********等待高電平信號接收結束******************/
while(Echo);
/*******************關閉T0計數(shù)********************/
TR0 = 0;
/**********高電平時間賦值,單位us*****************/
time = TH0*256 + TL0;
TH0 = 0;
TL0 = 0;
return time;
}
?
7.子函數(shù)6
? ? 動態(tài)數(shù)碼管顯示結果函數(shù)。用于控制動態(tài)數(shù)碼管顯示測量出的距離。
/**************************************動態(tài)數(shù)碼管顯示結果***********************************/
void xianshi(int d)
{
int k=8,m;
while(d!=0)
{
m=(d%10);//在數(shù)碼管上顯示個位,從后往前顯示
shumaguan(k,m);
k--;//數(shù)碼管向前移位
d=d/10;
}
}
?
六、系統(tǒng)測試??
?
測最近有效距離,為3cm。
?測最遠有效距離,為560cm。
?
?七、源代碼
#include <REGX51.H>
#include<intrins.h>
sbit Trig = P1^0;
sbit Echo = P1^1;
/******************************************延時函數(shù)***************************************/
void delay(unsigned int xms)//延時x毫秒
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=112;j>0;j--);
return;
}
/******************************************數(shù)碼管控制函數(shù)***************************************/
unsigned char shuzi[]={0x3f/*0*/,0x06/*1*/,0x5b/*2*/,0x4f/*3*/,0x66/*4*/,0x6d/*5*/,0x7d/*6*/,0x07/*7*/,0x7f/*8*/,0x6f/*9*/};//顯示的數(shù)字(num)的數(shù)組
void shumaguan(unsigned char wei,num)//第幾位(wei)顯示
{
switch(wei)
{
case 1:P0_2=0;P0_1=0;P0_0=0;break;
case 2:P0_2=0;P0_1=0;P0_0=1;break;
case 3:P0_2=0;P0_1=1;P0_0=0;break;
case 4:P0_2=0;P0_1=1;P0_0=1;break;
case 5:P0_2=1;P0_1=0;P0_0=0;break;
case 6:P0_2=1;P0_1=0;P0_0=1;break;
case 7:P0_2=1;P0_1=1;P0_0=0;break;
case 8:P0_2=1;P0_1=1;P0_0=1;break;
}
P3=shuzi[num];
delay(1);
}
/**********************************定時器函數(shù) 延時10us*************************************/
void Delay10us()
{
TMOD |= 0x01;//16位定時器/計數(shù)器
TH0 = 0xFF;//賦初值
TL0 = 0xF6;//賦初值
TR0 = 1;//啟動
while(!TF0);//溢出
TF0 = 0;//清溢出
}
/******************************************算距離函數(shù)***************************************/
float GetDistance(unsigned int time)
{
float distance;
distance = (float)time * 0.017;//cm 距離=高電平時間×聲速/2 0.017cm/us
return distance;//將距離返回主函數(shù)
}
/******************************************測時間函數(shù)***************************************/
unsigned int RunOnce()
{
unsigned int time;
/******************發(fā)送10us高電平信號*************/
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
/**************等待高電平信號接收*****************/
while(!Echo);
/*********T0清0重新計數(shù)(高電平持續(xù)時間)*********/
TH0 = 0;
TL0 = 0;
TR0 = 1;
/*********等待高電平信號接收結束******************/
while(Echo);
/*******************關閉T0計數(shù)********************/
TR0 = 0;
/**********高電平時間賦值,單位us*****************/
time = TH0*256 + TL0;
TH0 = 0;
TL0 = 0;
return time;
}
/**************************************動態(tài)數(shù)碼管顯示結果***********************************/
void xianshi(int d)
{
int k=8,m;
while(d!=0)
{
m=(d%10);//在數(shù)碼管上顯示個位,從后往前顯示
shumaguan(k,m);
k--;//數(shù)碼管向前移位
d=d/10;
}
}
/******************************************主函數(shù)***************************************/
void main()
{
unsigned int time = 0;
float distance;
while(1)
{
time = RunOnce();//傳感器接收到高電平的時間
distance = GetDistance(time);
xianshi(distance);
}
}
?
?
?
到了這里,關于【C語言】51單片機超聲波測距(實作 非仿真)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!