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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6623|回復: 4
收起左側

單片機超聲波測距不到一米,超出50厘米就不準了,附源碼

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

  2. /*軟件延時,延時時間(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. /* 獲取測量數據,返回值:以毫米位單位的距離值 */
  17. unsigned int GetDistance()
  18. {
  19.     float time;
  20.     float result;

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

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



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

  62. /* 等待液晶準備好 */
  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; //讀取狀態字
  72.         LCD1602_E = 0;
  73.     } while (sta & 0x80); //bit7等于1表示液晶正忙,重復檢測直到其等于0為止
  74. }
  75. /* 向LCD1602液晶寫入一字節命令,cmd-待寫入命令值 */
  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液晶寫入一字節數據,dat-待寫入數據值 */
  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. /* 設置顯示RAM起始地址,亦即光標位置,(x,y)-對應屏幕上的字符坐標 */
  96. void LcdSetCursor(unsigned char x, unsigned char y)
  97. {
  98.     unsigned char addr;

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

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




  126. #include "Ultrasonic.h"

  127. /*軟件延時,延時時間(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. /* 獲取測量數據,返回值:以毫米位單位的距離值 */
  142. unsigned int GetDistance()
  143. {
  144.     float time;
  145.     float result;

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

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



回復

使用道具 舉報

ID:213173 發表于 2018-4-26 20:57 | 顯示全部樓層
這種低成本玩藝本來就是練練手的,別指望有多完美。要想性能好就買工業級的產品。
回復

使用道具 舉報

ID:111634 發表于 2018-4-26 22:41 | 顯示全部樓層
不是因為“低成本玩藝”,而是程序有問題。
回復

使用道具 舉報

ID:317476 發表于 2018-4-26 23:50 | 顯示全部樓層
沒猜錯的話,超過50厘米是因為定時器溢出了,建議你用雙定時器,開始測量然后到收到回波,通過比較器得到精確計數,然后得到時間來算距離。
回復

使用道具 舉報

ID:300215 發表于 2018-4-28 12:10 | 顯示全部樓層
zzzy 發表于 2018-4-26 23:50
沒猜錯的話,超過50厘米是因為定時器溢出了,建議你用雙定時器,開始測量然后到收到回波,通過比較器得到精 ...

能不能說的再清楚點
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久久久久久久久久av | 午夜在线免费观看视频 | 九九热九九 | 精品国产一区二区三区免费 | 天天爱爱网| 国产精品久久久久久婷婷天堂 | 成人午夜免费网站 | 国产精品久久久久久久久久 | 欧美一级二级在线观看 | 日韩精品一区二区三区四区 | 国产亚洲精品久久久久动 | 日韩高清一区 | 亚洲欧洲视频 | 欧美日韩午夜精品 | 精品粉嫩超白一线天av | 久久久免费观看视频 | 99久久婷婷| 欧美三区在线观看 | 欧美 日韩 在线播放 | 午夜午夜精品一区二区三区文 | 精产国产伦理一二三区 | 日韩欧美第一页 | 狠狠草视频 | 亚洲黄色网址视频 | 91在线最新 | 欧美不卡 | 国产精品日日摸夜夜添夜夜av | 日韩av一区二区在线观看 | 亚洲一区二区欧美 | 日韩和的一区二在线 | 亚洲精品一区在线 | 国产欧美一区二区三区在线看 | 一区二区三区高清 | 午夜视频在线观看网站 | 国产精品久久久久久久久久久免费看 | 99国产在线| 久久成 | 国产精品福利网站 | 一级黄色夫妻生活 | 国产蜜臀97一区二区三区 | 久久成人人人人精品欧 |