找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 6642|回復(fù): 4
收起左側(cè)

單片機(jī)超聲波測(cè)距不到一米,超出50厘米就不準(zhǔn)了,附源碼

[復(fù)制鏈接]
ID:300215 發(fā)表于 2018-4-26 15:58 | 顯示全部樓層 |閱讀模式
超聲波測(cè)距不到一米,超出50厘米就不準(zhǔn)了
主程序
  1. #include "Ultrasonic.h"

  2. /*軟件延時(shí),延時(shí)時(shí)間(t*10)us*/
  3. void DelayX10us(unsigned char t)
  4. {
  5.     do {
  6.         _nop_();
  7.         _nop_();
  8.         _nop_();
  9.         _nop_();
  10.         _nop_();
  11.         _nop_();
  12.         _nop_();
  13.         _nop_();
  14.     } while (--t);
  15. }

  16. /* 獲取測(cè)量數(shù)據(jù),返回值:以毫米位單位的距離值 */
  17. unsigned int GetDistance()
  18. {
  19.     float time;
  20.     float result;

  21.     TH1 = 0;                  //定時(shí)器1清零,準(zhǔn)備本次測(cè)距計(jì)數(shù)
  22.     TL1 = 0;
  23.     Trig = 1;                 //Trig輸出高電平
  24.     DelayX10us(2);            //延時(shí)20us
  25.     Trig = 0;                 //Trig輸出低電平,至此產(chǎn)生一個(gè)20us的脈沖信號(hào)以啟動(dòng)超聲波模塊
  26.     while(!Echo);             //等待回波信號(hào),回波信號(hào)自動(dòng)使能T1計(jì)數(shù)
  27.     while(Echo);              //等待回波信號(hào)結(jié)束,T1同時(shí)自動(dòng)停止
  28.     if (TF1 == 1)             //TF1為1時(shí)說(shuō)明定時(shí)器溢出了
  29.     {
  30.         TF1 = 0;              //清除標(biāo)志位
  31.         time = 65535;         //溢出時(shí),直接設(shè)置為最大計(jì)數(shù)值
  32.     }
  33.     else
  34.     {
  35.         time = TH1*256 + TL1; //未溢出時(shí),讀取其實(shí)際計(jì)數(shù)值
  36.     }
  37.     time = time * (12/11.0592) / 2;  //將計(jì)數(shù)周期轉(zhuǎn)換為實(shí)際時(shí)間(us);超聲波測(cè)得的是來(lái)回距離,需要除以2得到單程距離所對(duì)應(yīng)的時(shí)間
  38.     result = (time/1000000) * 340;   // time(s)*速度 = 距離 ,340為聲波在空氣中的傳播速度(m/s)
  39.     if (result > 4.0)        //判斷是否超出模塊的測(cè)量范圍
  40.     {
  41.         result = 4.0;        //超出上限4m則設(shè)置為4m
  42.     }
  43.     else if (result < 0.02)
  44.     {
  45.         result = 0.02;       //低于下限0.02m則設(shè)置為0.02m
  46.     }
  47.     return (unsigned int)(result*1000);   //以無(wú)符號(hào)整形數(shù)返回測(cè)量結(jié)果,乘1000使其單位變?yōu)楹撩?br />
  48. }

  49. /*初始化超聲波模塊*/
  50. void InitUltrasonic()
  51. {
  52.     TMOD &= 0x0f;
  53.     TMOD |= 0x90;  //設(shè)置T1為方式1,GATE=1啟用門(mén)控模式;
  54.     TH1 = 0;
  55.     TL1 = 0;
  56.     ET1 = 0;       //關(guān)閉T0中斷
  57.     TR1 = 1;       //使能定時(shí)器,由于使用GATE位控制定時(shí)器啟停,所以定時(shí)器必須打開(kāi),啟停將由外部信號(hào)觸發(fā) 詳情參考 <手把手將你學(xué)51單片機(jī)> P59
  58.     Trig = 0;      //拉低模塊觸發(fā)引腳
  59. }



  60. #define  _LCD1602_C
  61. #include "Lcd1602.h"

  62. /* 等待液晶準(zhǔn)備好 */
  63. void LcdWaitReady()
  64. {
  65.     unsigned char sta;

  66.     LCD1602_DB = 0xFF;
  67.     LCD1602_RS = 0;
  68.     LCD1602_RW = 1;
  69.     do {
  70.         LCD1602_E = 1;
  71.         sta = LCD1602_DB; //讀取狀態(tài)字
  72.         LCD1602_E = 0;
  73.     } while (sta & 0x80); //bit7等于1表示液晶正忙,重復(fù)檢測(cè)直到其等于0為止
  74. }
  75. /* 向LCD1602液晶寫(xiě)入一字節(jié)命令,cmd-待寫(xiě)入命令值 */
  76. void LcdWriteCmd(unsigned char cmd)
  77. {
  78.     LcdWaitReady();
  79.     LCD1602_RS = 0;
  80.     LCD1602_RW = 0;
  81.     LCD1602_DB = cmd;
  82.     LCD1602_E  = 1;
  83.     LCD1602_E  = 0;
  84. }
  85. /* 向LCD1602液晶寫(xiě)入一字節(jié)數(shù)據(jù),dat-待寫(xiě)入數(shù)據(jù)值 */
  86. void LcdWriteDat(unsigned char dat)
  87. {
  88.     LcdWaitReady();
  89.     LCD1602_RS = 1;
  90.     LCD1602_RW = 0;
  91.     LCD1602_DB = dat;
  92.     LCD1602_E  = 1;
  93.     LCD1602_E  = 0;
  94. }
  95. /* 設(shè)置顯示RAM起始地址,亦即光標(biāo)位置,(x,y)-對(duì)應(yīng)屏幕上的字符坐標(biāo) */
  96. void LcdSetCursor(unsigned char x, unsigned char y)
  97. {
  98.     unsigned char addr;

  99.     if (y == 0)  //由輸入的屏幕坐標(biāo)計(jì)算顯示RAM的地址
  100.     {
  101.         addr = 0x00 + x;  //第一行字符地址從0x00起始
  102.     }
  103.     else
  104.     {
  105.         addr = 0x40 + x;  //第二行字符地址從0x40起始
  106.     }
  107.     LcdWriteCmd(addr | 0x80);  //設(shè)置RAM地址
  108. }
  109. /* 在液晶上顯示字符串,(x,y)-對(duì)應(yīng)屏幕上的起始坐標(biāo),str-字符串指針 */
  110. void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
  111. {
  112.     LcdSetCursor(x, y);   //設(shè)置起始地址
  113.     while (*str != '\0')  //連續(xù)寫(xiě)入字符串?dāng)?shù)據(jù),直到檢測(cè)到結(jié)束符
  114.     {
  115.         LcdWriteDat(*str++);
  116.     }
  117. }

  118. /* 初始化1602液晶 */
  119. void InitLcd1602()
  120. {
  121.     LcdWriteCmd(0x38);  //16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
  122.     LcdWriteCmd(0x0C);  //顯示器開(kāi),光標(biāo)關(guān)閉
  123.     LcdWriteCmd(0x06);  //文字不動(dòng),地址自動(dòng)+1
  124.     LcdWriteCmd(0x01);  //清屏
  125. }




  126. #include "Ultrasonic.h"

  127. /*軟件延時(shí),延時(shí)時(shí)間(t*10)us*/
  128. void DelayX10us(unsigned char t)
  129. {
  130.     do {
  131.         _nop_();
  132.         _nop_();
  133.         _nop_();
  134.         _nop_();
  135.         _nop_();
  136.         _nop_();
  137.         _nop_();
  138.         _nop_();
  139.     } while (--t);
  140. }

  141. /* 獲取測(cè)量數(shù)據(jù),返回值:以毫米位單位的距離值 */
  142. unsigned int GetDistance()
  143. {
  144.     float time;
  145.     float result;

  146.     TH1 = 0;                  //定時(shí)器1清零,準(zhǔn)備本次測(cè)距計(jì)數(shù)
  147.     TL1 = 0;
  148.     Trig = 1;                 //Trig輸出高電平
  149.     DelayX10us(2);            //延時(shí)20us
  150.     Trig = 0;                 //Trig輸出低電平,至此產(chǎn)生一個(gè)20us的脈沖信號(hào)以啟動(dòng)超聲波模塊
  151.     while(!Echo);             //等待回波信號(hào),回波信號(hào)自動(dòng)使能T1計(jì)數(shù)
  152.     while(Echo);              //等待回波信號(hào)結(jié)束,T1同時(shí)自動(dòng)停止
  153.     if (TF1 == 1)             //TF1為1時(shí)說(shuō)明定時(shí)器溢出了
  154.     {
  155.         TF1 = 0;              //清除標(biāo)志位
  156.         time = 65535;         //溢出時(shí),直接設(shè)置為最大計(jì)數(shù)值
  157.     }
  158.     else
  159.     {
  160.         time = TH1*256 + TL1; //未溢出時(shí),讀取其實(shí)際計(jì)數(shù)值
  161.     }
  162.     time = time * (12/11.0592) / 2;  //將計(jì)數(shù)周期轉(zhuǎn)換為實(shí)際時(shí)間(us);超聲波測(cè)得的是來(lái)回距離,需要除以2得到單程距離所對(duì)應(yīng)的時(shí)間
  163.     result = (time/1000000) * 340;   // time(s)*速度 = 距離 ,340為聲波在空氣中的傳播速度(m/s)
  164.     if (result > 4.0)        //判斷是否超出模塊的測(cè)量范圍
  165.     {
  166.         result = 4.0;        //超出上限4m則設(shè)置為4m
  167.     }
  168.     else if (result < 0.02)
  169.     {
  170.         result = 0.02;       //低于下限0.02m則設(shè)置為0.02m
  171.     }
  172.     return (unsigned int)(result*1000);   //以無(wú)符號(hào)整形數(shù)返回測(cè)量結(jié)果,乘1000使其單位變?yōu)楹撩?br />
  173. }

  174. /*初始化超聲波模塊*/
  175. void InitUltrasonic()
  176. {
  177.     TMOD &= 0x0f;
  178.     TMOD |= 0x90;  //設(shè)置T1為方式1,GATE=1啟用門(mén)控模式;
  179.     TH1 = 0;
  180.     TL1 = 0;
  181.     ET1 = 0;       //關(guān)閉T0中斷
  182.     TR1 = 1;       //使能定時(shí)器,由于使用GATE位控制定時(shí)器啟停,所以定時(shí)器必須打開(kāi),啟停將由外部信號(hào)觸發(fā) 詳情參考 <手把手將你學(xué)51單片機(jī)> P59
  183.     Trig = 0;      //拉低模塊觸發(fā)引腳
  184. }
復(fù)制代碼



回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2018-4-26 20:57 | 顯示全部樓層
這種低成本玩藝本來(lái)就是練練手的,別指望有多完美。要想性能好就買(mǎi)工業(yè)級(jí)的產(chǎn)品。
回復(fù)

使用道具 舉報(bào)

ID:111634 發(fā)表于 2018-4-26 22:41 | 顯示全部樓層
不是因?yàn)椤暗统杀就嫠嚒保浅绦蛴袉?wèn)題。
回復(fù)

使用道具 舉報(bào)

ID:317476 發(fā)表于 2018-4-26 23:50 | 顯示全部樓層
沒(méi)猜錯(cuò)的話,超過(guò)50厘米是因?yàn)槎〞r(shí)器溢出了,建議你用雙定時(shí)器,開(kāi)始測(cè)量然后到收到回波,通過(guò)比較器得到精確計(jì)數(shù),然后得到時(shí)間來(lái)算距離。
回復(fù)

使用道具 舉報(bào)

ID:300215 發(fā)表于 2018-4-28 12:10 | 顯示全部樓層
zzzy 發(fā)表于 2018-4-26 23:50
沒(méi)猜錯(cuò)的話,超過(guò)50厘米是因?yàn)槎〞r(shí)器溢出了,建議你用雙定時(shí)器,開(kāi)始測(cè)量然后到收到回波,通過(guò)比較器得到精 ...

能不能說(shuō)的再清楚點(diǎn)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表