久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8027|回復: 10
打印 上一主題 下一主題
收起左側

[討論]超聲波測距

[復制鏈接]
跳轉到指定樓層
樓主
ID:15556 發表于 2009-12-9 21:54 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
請教有關超聲波測距的問題,有經驗的可以交流下
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:21971 發表于 2010-3-6 15:30 | 只看該作者

目前,現有的超聲波發生器有40KHz,48KHz,58KHz等頻率。根據聲波在空氣中(25攝氏度時)的速度340米每秒,來計算距離。其中一關鍵數據是超聲波從發射到返回之間的時間(除以2),以此來計算時間;從而得到距離,之后再進行距離方面的提示工作,現有的倒車雷達便是如此。以上請知悉......

回復

使用道具 舉報

板凳
ID:22031 發表于 2010-3-20 19:53 | 只看該作者
正在等程序,新手,誰搞過的共享一下程序啊- -
回復

使用道具 舉報

地板
ID:26649 發表于 2010-11-2 20:32 | 只看該作者
我也等!!!!
回復

使用道具 舉報

5#
ID:60076 發表于 2014-4-5 04:10 | 只看該作者
這個程序在分的很細,可以看超聲部分或溫濕檢測部分程序。
程序如下:
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define Data  P1   //LCD1602的數據口
#define NOP() {_nop_();_nop_();_nop_();_nop_();} //用于延時

//LCD1602控制引腳定義
//sbit RS = P2^6;
//sbit RW = P2^5;
//sbit E = P2^7;
sbit RS = P2^0; //復位端
sbit RW = P2^1; //寫數據端
sbit E = P2^2; //使能端
//溫濕DHT11的數據引腳定義
sbit DHT=P2^3;
//這些數組用于數據的緩存
uchar wendu_char[]=" temperature";//12  用于提示的字符
uchar shidu_char[]="  humidity";//10   用于提示的字符
uchar  wendu[] ="wen:00.00 d";//11  數據格式,當讀取的數據會保存到數組的相應的位上
uchar  shidu[]="shi:00.00 RH";//12  //同上一句
uchar table[]={" make ^!^ in  "};//14   //用于提示
uchar table1[]={" 2013-12-20 "};//12   //用于提示
//uchar qingxu1[]={"   ^!^    "};//11
//uchar qingxu2[]={"good weather"};//12
//uchar qingxu3[]={"   -_-!    "};//12
//uchar qingxu4[]={"bad weather!"};//12
unsigned char shiZ,shiX,wenZ,wenX,check;  //用于存讀出傳感器的數據,因為讀出的是整型數據,之后用于轉換成字符存于上面的數組中
unsigned char shiH,shiL,wenH,wenL;  //
unsigned char flag;  //定義一個標志位
unsigned int n=20,m;   //定義一些會在下面用到的全局變量
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void delay(uint a); //超聲波模塊和溫濕模塊的公用延時函數
void delay_10us() ;
void delay_1ms(unsigned int i) ;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//超聲波部分的函數
/////////////////////////////////////////////////////
sbit Tx=P3^3;    //超聲波模塊發射脈沖的引腳定義
sbit Rx=P3^2;    //超聲波模塊接收回波的引腳定義
uchar code table2[]={"Distance Test:"}; //14   //用于提示
uchar temp_dis[]= {"000.0 cm"};// 8       //用于顯示數據的緩沖數組
long int t;//讀出的數據現存于這些變量,再轉換成字符賦給上面的數組
double distance;
uchar cache[4]={0,0,0,0};  //用于裝入分離的數據的各個位
//外部中斷0用于計算超聲波模塊接收到回波的時間,用于計算距離
void init0() //外部中斷0在接收到Rx腳的高電平觸發定時器計時,當高電平回波結束時是下降沿
{//定時器0的初始化
TMOD=0x01;  
TH0=0;
TL0=0;

//外部中0的初始化
EX0=1; //外部中斷的
IT0=1;      //設置為低電平觸發,下降沿有效

//打開總中斷
//EA=1;
}

//超聲波模塊初始化
void HC05_Init()
{ //依據模塊的資料,把發射腳拉高大于10us,再把發射腳拉低,模塊就會自動發送探測的脈沖
  EA=1;
  Tx=1;  
  NOP();NOP();NOP();NOP(); //用于延時,保持大于8us的要求
  Tx=0;  //發射腳拉低
  while(!Rx);  //當RX為零時等待
  TR0=1;       //開啟計數
  while(Rx);   //當RX為1計數并等待
  TR0=0;    //關閉計數
  //TR0=1; //打開定時器0,以便從發送脈沖開始計時,到接收到外部中斷0后關閉
  distance=0.17*t;  //計算距離的公式
// distance=(340*t)/2;
}

//數值轉換
void distance_convert(long int dat)
{  
  //把得到的數據分離出個,十,百等位,裝入數組中
//0.17*t知道測量的值有兩個小數點,且該超聲波模塊可以測量到幾百厘米,所以,得到的數據格式位000.00cm,
//我們要保留1為小數,又因為\,%的運算為整數,則先把數據乘以10,再求出各個對應的位放到對應的數組
  //dat=dat*10;
  cache[0]=dat/1000; //實際對應原數據的百位,因為把數據*10處理了,向高位移了一位
  cache[1]=dat/100;
  cache[2]=dat/10;
  cache[3]=dat; //
  //裝入數組,加'0'是將整型的數據轉換成字符數據
  temp_dis[0]=cache[0]+'0'; //數組的格式位uchar temp_dis[]= {"000.0 cm"};
  temp_dis[1]=cache[1]+'0';
  temp_dis[2]=cache[2]+'0';
  temp_dis[4]=cache[3]+'0';
}

//溫度度部分的函數(DHT11)
////////////////////////////////////

//延時函數1ms
void delay_1ms(unsigned int i)
{
  unsigned int j=88;
  for(;i>0;i--)
  {
  while(j>0)j--;
  }
}
//延時函數10us
void delay_10us()
{
  unsigned char i;
  i--;
  i--;
  i--;
  i--;
  i--;
  i--;
}
//延時函數可調
void delay(uint a)
{
uint y;
for(;a>0;a--)
  for(y=100;y>0;y--);
}


//讀取DHT11的數據,其為單總線通訊,只用一條線,已經定義為DHT,區別于I2C通訊
char read_data()
{
  unsigned char i,num,temp;
  num=0;
  for(i=0;i<8;i++)
  {
  flag=2;
  while((!DHT)&&flag++); //判斷從機是否發出80us的低電平相應信號是否結束
  delay_10us();
  delay_10us();
  delay_10us();
   if(DHT==1)
   {
    temp=1;
    flag=2;
    while(DHT&&flag++);   
   } //超時則跳出
  else
   temp=0;
   num<<=1; //一位一位的讀出存入變量num中
   num|=temp;
  }
  return(num); //讀8個位的數據,為一個字節
}

//讀取DHT11的40位數據函數//////////////////////////////////////////////////////////////////////////////
void read_init()
{
  DHT=0;   //主機拉低21ms
  delay_1ms(21);
  DHT=1;    //總線由上拉電阻拉高40us
  delay_10us();
  delay_10us();
  delay_10us();
  delay_10us();
  DHT=1; //主機設為輸入 判斷從機相應信號
  if(!DHT)  //判斷從機是否把總線拉低
  {
   flag=2;
   while((!DHT)&&flag++); //等待從機把總線拉低
   flag=2;
   while(DHT&&flag++); //判斷從機是否拉低總線,即響應
    //接收數據
   shiH=read_data();//因為read_data()只讀出一個字節,而DHT讀出的是連續的5個字節,所以不用for()
   shiL=read_data();
   wenH=read_data();
   wenL=read_data();
   check=read_data();
   DHT=1;
  }      
}

//DH11數據處理
void DHT11dada()
{
unsigned char temp;
read_init();
  temp=shiH+shiL+wenH+wenL; //檢驗也為8位的二進制,等于前面的數據之和
  if(check==temp)
  {  //檢驗數據對了就賦給另外幾個變量來轉換
    shiZ=shiH;
    shiX=shiL;
    wenZ=wenH;
    wenX=wenL;
  }
  wendu[4]='0'+wenZ/10; //分離出各個位,并轉換成字符數據,依據上面的數組定義wendu[] ="wen:00.00 d";的數據格式,把對應的數據寫到對應的位
  wendu[5]='0'+wenZ;  //分理出的是溫度的個位,在數組中的第六個位置,所以寫入該位更新,以便顯示
  wendu[8]='0'+wenX/10;  //第七位為 .
  wendu[9]='0'+wenX;
  shidu[4]='0'+shiZ/10; //同理,濕度的格式為shidu[]="shi:00.00 RH";
  shidu[5]='0'+shiZ;
  shidu[8]='0'+shiX/10;
  shidu[9]='0'+shiX;
}


//LCD1602部分函數     各個函數依據LCD1602的時序編寫
////////////////////////////////////////////////////////

//LCD1602寫指令函數
void lcd_write_com(uchar c)   
{
  delay_1ms(5);
  E=0;
  RS=0;
  RW=0;
  _nop_();
  E=1;
  Data=c;
  E=0;
}

//LCD1602寫數據函數
void lcd_write_dat(uchar c)  
{
  delay_1ms(5);
  E=0;
  RS=1;
  RW=0;
  _nop_();
  E=1;
  Data=c;
  E=0;
  RS=0;
}

//LCD1602初始化
void lcd_init()   
{
  delay_1ms(5);
  lcd_write_com(0x38);
  lcd_write_com(0x38);
  lcd_write_com(0x38);
  lcd_write_com(0x06);
  lcd_write_com(0x0c);
  lcd_write_com(0x01);
}
//LCD1602清屏函數
void qingping()
{
lcd_write_com(0x01);
delay(5);
}

//顯示開始標題
void disp(void)    //顯示子函數
{ uchar i,j;
lcd_write_com(0x80);//往第一行寫入字符串,寫完一個字符會自動調到第二個地址寫入數據
  for(i=0;i<13;i++)
  {
   lcd_write_dat(table[ i]);
  }
lcd_write_com(0x80+40);//往第二行寫入日期
for(j=0;j<11;j++)
  {
   lcd_write_dat( table1[j]);
  }
  delay(3000);//顯示的時間長短
  qingping();//清屏
}

//顯示溫濕函數
void display_DHT11()
{ uchar h,n,e,m;
//uchar x,y;
lcd_write_com(0x80);
  for(e=0;e<12;e++)  //寫入溫度數據
   {
    lcd_write_dat(wendu_char[e]);
   }
  lcd_write_com(0x80+40);
  for(n=0;n<11;n++)  //寫入溫度數據
   {
    lcd_write_dat(wendu[n]);
   }
  delay(3000);
  qingping();//清屏
  lcd_write_com(0x80);
  for(h=0;h<10;h++) //寫入濕度數據
   {
    lcd_write_dat(shidu_char[h]);
   }
  lcd_write_com(0x80+40);
  for(m=0;m<12;m++) //寫入濕度數據
   {
    lcd_write_dat(shidu[m]);
   }
  delay(3000);
  qingping();

//  //情緒表達部分   //因為51內存寫滿了,只能舍去這部分
//  if(shiZ>=16&&shiZ<=28)
//  {
//   lcd_write_com(0x80);
//   for(y=0;y<11;y++)
//   {
//    lcd_write_dat(qingxu1[y]);
//   }
//  lcd_write_com(0x80+0x40);
//  for(x=0;x<12;x++)
//   {
//    lcd_write_dat(qingxu2[x]);
//   }
//   delay(3000);
//   qingping();
//  }
//  if(shiZ<=16&&shiZ>=28)
//  {
//   lcd_write_com(0x80);
//   for(y=0;y<12;y++)
//   {
//    lcd_write_dat(qingxu3[y]);
//   }
//  lcd_write_com(0x80+0x40);
//  for(x=0;x<12;x++)
//   {
//    lcd_write_dat(qingxu4[x]);
//   }
//   delay(3000);
//   qingping();
//  }
}

//顯示超聲波數據
void display_HC05()
{  
  uchar k,w;
  lcd_write_com(0x80);//超聲波測距顯示部分:K,W
  for(k=0;k<14;k++)
   {
    lcd_write_dat(table2[k]);
   }
  lcd_write_com(0x80+0x40);
  for(w=0;w<8;w++)
   {
    lcd_write_dat(temp_dis[w]);
   }
  delay(3000);
  qingping();
}
////不寫在一起是為了及時將數據輸出,因為讀完傳感器才輸出,有的傳感器的數據已經變化了
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//主函數
void main()
{  uchar x,s;
  lcd_init();
  init0();
  Tx=0;//超聲波發送口初始化,
  while(1)
  {
  disp();//顯示開始的字符
  for(x=0;x<2;x++)
  {
   DHT11dada();//溫濕的數據
  }
  display_DHT11();//顯示溫濕的數據
  for(s=0;s<2;s++)
  {
   HC05_Init(); //需要放到while(1)中 因為要不斷觸發超聲波模塊的脈沖得出距離
   distance_convert(distance);
  }
  display_HC05();
}
}


//外部中斷0的中斷函數,記回波的時間,即發送測量脈沖開始計時,到接收到回波時產生外部中斷,把得到的時間賦給t
void int0() interrupt 0
{  EA=0;
  t=(TH0*256+TL0);  //讀取定時器的時間
  TH0=0; //清空定時器
  TL0=0;
}
回復

使用道具 舉報

6#
ID:61326 發表于 2014-5-2 19:50 | 只看該作者
謝謝分享
回復

使用道具 舉報

7#
ID:56795 發表于 2014-5-3 17:02 來自手機 | 只看該作者
幾塊錢的超聲波測距模決是不是測距不穩定,我做的測同一距離會測出不同的數據。誤差有幾個毫米
回復

使用道具 舉報

8#
ID:56795 發表于 2014-5-3 17:04 來自手機 | 只看該作者
我不知道是程序有問題或是超聲波模塊有問題
回復

使用道具 舉報

9#
ID:28571 發表于 2015-4-18 14:12 | 只看該作者
好東西,學習一下,謝謝!
回復

使用道具 舉報

10#
ID:128255 發表于 2016-6-30 15:36 | 只看該作者
賣的模塊,普遍測量角度都在15度以內,分離模塊能達到多大的角度?
回復

使用道具 舉報

11#
ID:223039 發表于 2017-8-3 18:35 | 只看該作者
學習一下,樓主分享的很好!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 粉嫩av久久一区二区三区 | 成人黄色av网址 | 黄色一级大片视频 | 亚洲激精日韩激精欧美精品 | av中文字幕在线 | 国产免费xxx | 久久99精品久久久久久秒播九色 | 欧美a在线 | 国产精品久久久久久一区二区三区 | 国产精品视频久久 | 亚洲国产成人在线视频 | 亚洲视频中文字幕 | 91精品亚洲 | 美女福利视频网站 | 亚洲一区二区免费 | 国产二区视频 | 欧美日韩国产在线观看 | 99色视频| 国产一区久久 | 在线观看av网站 | 久久亚洲春色中文字幕久久久 | 天天操夜夜骑 | 91资源在线 | 亚洲欧美在线观看 | 日韩成人一区二区 | 久久久久免费精品国产 | 99精品国自产在线 | 人人干免费 | 国产露脸国语对白在线 | 紧缚调教一区二区三区视频 | av播播| 成人一区二区三区在线观看 | 久久精品一级 | 国产在线资源 | 一级午夜aaa免费看三区 | 超碰美女在线 | 一区二区三区四区视频 | 欧美男人的天堂 | 一区二区三区亚洲 | 精品视频一区二区三区 | 中文字幕一区在线观看视频 |