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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機+超聲波測距模塊數碼管顯示問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:381345 發表于 2018-8-3 21:56 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
請問各位大佬,我想讓超聲波測出來的距離顯示在數碼管上,但是我這個程序只在開電的瞬間測出距離并顯示在數碼管上,然后數碼管就一直顯示那個數字,超聲波也不工作了,請問怎么回事?代碼如下。謝謝。。。

  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include <STDIO.H>

  4. /* 1m所需周期:1000mm/(1微秒的聲波距離mm * 1周期的us時間) => 1000/(0.17*1.0851);
  5.    4m = 1000/(0.17*1.0851) * 4 = 21684   */
  6. #define uchar unsigned char
  7. #define iMAX_LEN 21684
  8. #define iMIN_LEN 109

  9. sbit trig = P3^0;
  10. sbit echo = P3^1;

  11. sbit ADDR0 = P1^0;
  12. sbit ADDR1 = P1^1;
  13. sbit ADDR2 = P1^2;
  14. sbit ADDR3 = P1^3;
  15. sbit ENLED = P1^4;

  16. /****************V數碼管模塊*****************************************************************************/
  17. unsigned char code LedChar[] = {  //數碼管顯示字符轉換表
  18.                                0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  19.                                0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  20.                                };
  21. unsigned char LedBuff[6] = {  //數碼管顯示緩沖區,初值0xFF確保啟動時都不亮
  22.                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  23.                            },
  24.                           buf[6],
  25.                           i = 0,
  26.                           j;
  27. /*************** ^超聲波模塊*****************************************************************************/

  28. /****************V超聲波模塊*****************************************************************************/         
  29. unsigned long miDistance=0, //測距的距離值
  30.               distance = 0;
  31. uchar mcDistanceErr=0; //測距錯誤標記(0:正常 / 1:距離太近 /2:超量程)
  32. bit mbDelayOverFlg = 1;        //延遲程序的控制標記(默認為延遲結束否則無法進入refreshDistance()函數)
  33. uchar mbDelay10H, mbDelay10L; //測距的小單位時間延遲
  34.          
  35. /* 定時器函數,T1計數器使用3號中斷
  36. *作用:用于延遲出發測距,每次測距完成后,需要延遲>60ms
  37. *因此當計數器溢出時,time=65.535ms,mbDelayCtlFlg=1    */
  38. void tim1_()interrupt 3
  39. {        
  40.         TR1 = 0; //T1關閉計數器
  41.         mbDelayOverFlg = 1; //設定延遲結束
  42. }
  43.          
  44. /*啟動超聲波測距模塊,TX保持22us的高電平*/
  45. void StartModule()
  46. {
  47.     trig = 1; //控制端置1
  48.         _nop_();
  49.         _nop_();
  50.         _nop_();
  51.         _nop_();
  52.         _nop_();
  53.         _nop_();
  54.         _nop_();
  55.         _nop_();
  56.         _nop_();
  57.         _nop_();
  58.         _nop_();
  59.         _nop_();
  60.         _nop_();
  61.         _nop_();
  62.         _nop_();
  63.         _nop_();
  64.         _nop_();
  65.         _nop_();
  66.         _nop_();
  67.         _nop_();
  68.         _nop_();
  69.         trig = 0; //控制端置0,等待接收回波
  70. }
  71.          
  72. /*獲取最近一次測得的距離
  73. *注意:每次成功測距,需要耗時100ms-150ms左右時間*/
  74. unsigned int getDistance(void)
  75. {
  76.         return miDistance;
  77. }
  78.          
  79. /*獲取最近一次的測距狀態
  80. *@return unsigned int 0:正常 / 1:(err)距離太近 /2:(err)超量程*/
  81. unsigned int getDistanceState(void)
  82. {
  83.         return mcDistanceErr;
  84. }
  85.          
  86. /*檢查距離操作(將測得的距離保存在公共變量中)
  87. *備注:本函數調用完成后,需要通過getDistance()或getDistanceState()獲得結果
  88. *注意:每次成功測距,需要耗時100ms-150ms左右時間
  89. *@return 0:完成測距操作 / 1:正在延遲等待下次測距的開始*/
  90. unsigned char refreshDistance(void)
  91. {
  92.         unsigned int i; //超量程檢測變量
  93.         unsigned int iCycle; //計算總周期         
  94.         if (1 == mbDelayOverFlg)//判斷是否在延遲期
  95.         {        
  96.                 i = iMAX_LEN; //置入最大量程
  97.                 StartModule(); //發送測距模塊啟動信號
  98.                 /*此語句的作用:
  99.                 *沒有收到回波且在N(iMAX_LEN*N)米障礙物信號返回需要的時間前則等待
  100.                 *(無信號即時返回,防止死循環,阻礙其它程序的執行)*/
  101.                 while(!echo && i-->0);
  102.                 //判斷處理結果
  103.                 if (i>0) //小于N米
  104.                 {
  105.                         TR1=1; //收到回波的上邊沿(RX=1),打開計數器
  106.                         while(echo);//當回波RX=0時,測距結束
  107.                         TR1=0; //關閉定時器(需要一個時鐘周期)
  108.                         iCycle = (TH1 * 256 + TL1) + 1; //計算總消耗的周期
  109.                         TH1=0;
  110.                         TL1=0;               
  111.                         if (iCycle <= iMIN_LEN)
  112.                         {
  113.                                 mcDistanceErr = 1;//距離太近
  114.                                 /*距離超近:重啟延遲時間 >10ms,保證上一個聲波回波已經消失
  115.                             *T0計數器重裝值mbDelay10H, mbDelay10L,在
  116.                                 *InitUltrasonicDistance()初始化函數中生成*/
  117.                                 miDistance = 2;
  118.                                 mbDelayOverFlg = 0; //復位延遲標志
  119.                                 TH1 = mbDelay10H; //重裝計數器高8位
  120.                                 TL1 = mbDelay10L; //重裝計數器低8位
  121.                                 TR1 = 1; //啟動延遲計數器
  122.                         }
  123.                         else
  124.                         {
  125.                                 //(iCycle * 1.0851 * 0.17 / 10) => iCycle * 0.01844670
  126.                                 miDistance = (unsigned int)(iCycle * 184467 / 10000000);//(單位cm)
  127.                                 mcDistanceErr = 0;//測距正常值
  128.                                 /*一次測距完成需要延遲>60ms的時間,保證上一個聲波回波已經消失
  129.                                 * 這兒使用16位計數器的整個空間,> 65.535ms        */
  130.                                 mbDelayOverFlg = 0; //復位延遲標志
  131.                                 TH1 = 0; //T0,高位歸0復位
  132.                                 TL1 = 0; //T0,低位歸0復位
  133.                                 TR1 = 1;//打開T0延遲計數器(此時不測距,所以不影響測距的計算)
  134.                         }
  135.                 }
  136.                 else
  137.                 {
  138.                     mcDistanceErr = 2; //超量程
  139.                         miDistance = 400;
  140.                 }         
  141.                 return 0; //完成測距操作
  142.         }
  143.         else //正在延遲等待下次測距的開始
  144.         return 1;
  145. }
  146. /*************** ^超聲波模塊*****************************************************************************/

  147. //************數碼管顯示
  148. void display(unsigned long sec)
  149. {
  150.     buf[0] = sec%10;
  151.     buf[1] = sec/10%10;
  152.     buf[2] = sec/100%10;
  153.     //從最高為開始,遇到0不顯示,遇到非0退出循環
  154.     for (j=2; j>=1; j--)
  155.     {
  156.          if (buf[j] == 0)
  157.          LedBuff[j] = 0xFF;
  158.          else
  159.          break;
  160.     }
  161.     //將剩余的有效數字位如實轉換
  162.     for ( ; j>=0; j--)  //for()起始未對j操作,j即保持上個循環結束時的值
  163.     {
  164.          LedBuff[j] = LedChar[buf[j]];
  165.     }
  166. }

  167. void main(void)
  168. {
  169.         unsigned int delay_10ms;

  170.         ADDR3 = 1;
  171.         ENLED = 0;

  172.     TMOD |= 0x01;         
  173.         TH0  = 0xFC;  //為T0賦初值0xFC67,定時1ms
  174.     TL0  = 0x67;
  175.     ET0  = 1;     //使能T0中斷
  176.     TR0  = 1;     //啟動T0

  177.     TMOD |= 0x10;
  178.         TH1=0; //高位置0
  179.         TL1=0; //低位置0
  180.         TR1=0; //開始前先關閉計數器
  181.         ET1=1; //允許T0中斷

  182.     EA = 1;

  183.         delay_10ms = (unsigned int)(65536-110592/12); //10ms的延遲提前計算
  184.         mbDelay10H = delay_10ms >> 8; //高8位值
  185.         mbDelay10L = delay_10ms &0x0F; //低8位值

  186.         while(1)
  187.         {
  188.                 //當調用測距函數后,返回為0,表示測距成功,否則測距函數正在延遲中
  189.                 if (0 == refreshDistance())
  190.                 {
  191.                         //當取值有效時,如果與前次值沒變化,則不作更新
  192.                         if (0 == getDistanceState() && (distance != getDistance()))
  193.                         {
  194.                                 distance = getDistance();
  195.                                 display(distance);
  196.                         }
  197.                 }
  198.         }
  199. }

  200. /* 定時器0中斷服務函數 */
  201. void InterruptTimer0() interrupt 1
  202. {
  203.         TH0 = 0xFC;  //重新加載初值
  204.     TL0 = 0x67;
  205.     P0 = 0xFF;   //顯示消隱
  206.     switch (i)
  207.     {
  208.         case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
  209.         case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
  210.         case 2: ADDR2=0; ADDR1=1; ADDR0=0; i=0; P0=LedBuff[2]; break;
  211.         default: break;
  212.     }
  213. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:123289 發表于 2018-8-5 10:19 | 只看該作者
你把程序整理成邏輯框圖就明白了、
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩一区二区在线观看 | 一区二区三区久久久 | 国产亚洲欧美日韩精品一区二区三区 | 国产成人精品一区二区三区在线观看 | 国产精品一区二区三区久久 | 91看片在线 | 天天操天天干天天透 | 欧美综合国产精品久久丁香 | 午夜影视免费片在线观看 | 欧美一区二区三区国产 | 国产精品日韩一区二区 | 99久久精品国产麻豆演员表 | 天天看天天操 | 视频在线一区二区 | 国产精品国产三级国产a | 久久久久久久久久一区 | www.亚洲一区 | 91精品麻豆日日躁夜夜躁 | 在线免费观看欧美 | 一区二区中文字幕 | 国产九九九 | 国产日韩精品一区二区 | 中文字幕一区二区三区乱码图片 | 精品无码久久久久久国产 | 午夜精品一区二区三区在线视频 | 国产精品人人做人人爽 | 男女视频91| 毛片一级网站 | 日韩中文字幕在线观看视频 | 天天干夜夜操视频 | 亚洲精久久久 | 精品国产乱码久久久久久蜜臀 | av网站免费观看 | 国产做a爱片久久毛片 | 久久lu | 好婷婷网 | 久久久久久99 | 午夜激情视频在线 | 国产91久久久久蜜臀青青天草二 | 视频一区中文字幕 | 亚洲 欧美 综合 |