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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

STC89C52單片機控制超聲波測距模塊SR04,帶溫度矯正,存儲內部EEPROM,顯示在數碼管上

[復制鏈接]
跳轉到指定樓層
樓主
本代碼基于QH - 5A平臺,測試通過,適用于51系列單片機平臺,不同的型號只需要移植一下即可,SR04超聲波模塊是一個精度較高的測距模塊,本人測試精度1cm,模塊可直接與開發板連接,具體連接請參考本貼下面的內容,連接模塊時一定要斷電連接,不要帶電操作,容易損壞并且工作可能不正常。模塊實物如下圖所示:



開發板圖片:

1、SR04模塊主要技術參數:
1.使用電壓:DC5V
2.靜態電流:小于2mA
3:電平輸出:高5V
4:電平輸出:低0V
5:感應角度:不大于15度
6:探測距離:2cm-450cm
7:高精度:可達3mm

2、接線方式:VCC、trig(控制端)、 echo(接收端)、 GND地線(若采用QH-5A開發板直接插上即可)
3、使用方法:      一個控制口trig發一個10US以上的高電平,就可以在接收口echo等待高電平輸出.一有輸出就可以開定時器計時,當echo此口變為低電平時就可以讀定時器的值,此時就為此次測距的時間,方可算出距離.如此不斷的周期測,就可以達到你移動測量的值了~~
4、模塊工作原理:
   (1)采用IO觸發測距,給至少10us的高電平信號;
   (2)模塊自動發送8個40khz的方波,自動檢測是否有信號返回;
   (3)有信號返回,通過IO輸出一高電平,高電平持續的時間就是超聲波從發射到返回的時間.測試距離=(高電平時間*聲速(340M/S))/2或距離=(331.4+0.61*當前溫度)*定時器時間/2000000 CM;


5、程序功能:
本程序是采用第二公式編寫的,顯然有溫度矯正的超聲波測距更加準確,同時本程序還帶有內部存儲功能,可設定報警距離,程序有詳細注釋
水平有限,本程序只供學習,歡迎大家一起交流

單片機源程序如下:
  1. /*-----------------------------------------------
  2.   說明:
  3.         功能:超聲波測距,DS18b20矯正;數碼管顯示
  4.         晶振:12MHz
  5.         測量范圍:1CM - 500CM
  6.         溫度顯示:0.0 C - 99.9 C
  7.         警報范圍設置:5CM - 400CM(可以永久存儲設定值)
  8. ------------------------------------------------*/
  9. #include "reg52.h" //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
  10. #include "18b20.h"
  11. #include "eeprom.h"
  12. #include "delay.h"

  13. #define DataPort P0 //定義數據端口 程序中遇到DataPort 則用P1 替換
  14. sbit DUAN=P2^6;//定義鎖存使能端口 段鎖存
  15. sbit WEI=P2^7;//                 位鎖存

  16. /***************超聲波引腳定義******************/
  17. sbit Echo = P3 ^ 3;         //回波引腳
  18. sbit Trig = P1 ^ 5;         //觸發引腳

  19. sbit buzzer = P1 ^ 0;    //蜂鳴器引腳
  20. /*****************按鍵定義**********************/
  21. uchar bdata key,key1,lastkey;
  22. bit key1Mark;//設置鍵標志

  23. /*****************測距變量**********************/
  24. uchar EchoTimeH,EchoTimeL;  //自定義寄存器存儲8位回波時間
  25. uint Distance,EchoTime;            //測量距離,回波總時間
  26. uint Distance_Alarm;                                //報警距離通過自己設定(初始為0)
  27. bit succeed_flag;                              //測量成功標志

  28. uchar code Table[18] = //段碼表
  29. {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 顯示段碼值0~9
  30. uchar code WeiMa[4]={0xfe,0xfd,0xfb,0xf7};         //分別對應相應的數碼管點亮,即位碼

  31. uint Temperature,temp;//讀取溫度
  32. bit flag200ms,flag300ms;//獲取時間標志

  33. /*****************顯示變量**********************/
  34. uint DispData;
  35. uchar TempData[4]; //存儲顯示值的全局變量
  36. uchar mod;//顯示模式切換

  37. /*****************函數聲明**********************/
  38. void delay_20us();                                                                //20us延遲
  39. void CountDat(uint ShowData);                        //顯示數據處理
  40. void readkey();                                                                                //按鍵讀取
  41. void CountKey();                                                                        //顯示散轉
  42. void CSBFunction();                                                                //超聲波測距
  43. void Display();                                                                                //數碼管顯示函數
  44. void Init_Timer0(void);                                                //定時器0初始化

  45. /*------------------------------------------------
  46.                     主函數
  47. ------------------------------------------------*/
  48. void main (void)
  49. {                         
  50.         float speed = 0;

  51.         buzzer=1;     //初始化蜂鳴器引腳
  52.         Trig=0;       //首先拉低脈沖輸入引腳
  53.         TMOD|=0x11;    //定時器0,定時器1,16位工作方式
  54.   IT1=0;        //低電平觸發外部中斷
  55.         EX1=0;        //關閉外部中斷
  56.   Init_Timer0();
  57.         ISP_IAP_readData(0x2ff0,ReadBuf,2);
  58.         Distance_Alarm = ReadBuf[0] | (ReadBuf[1] << 8);//讀取警報距離值
  59.         while (1)         //主循環
  60.   {
  61.                 CSBFunction();        //開始測距
  62.                 if(succeed_flag)
  63.     {
  64.                         succeed_flag=0; //清測量成功標志        
  65.                    EchoTime = (EchoTimeH << 8) | EchoTimeL;                //與低8位合并成為16位結果數據
  66.                         //公式說明: 1、V=(331.4+0.61*T)*D/2000000 CM;2、回波時間D是us單位,最終
  67.                         //距離以CM單位要除以20000,這里為了減小計算量轉成uchar,先/200,再/100;
  68.                         speed = (331.4 + 0.61 * (TempData[0]*10+TempData[1])) / 200;
  69.                          Distance = (EchoTime * speed) / 100;     //算出來是CM
  70.                         CountDat(DispData);//計算需要顯示數據的各個位
  71.     }
  72.                 if(mod != 2)
  73.                         readkey();//按鍵讀取,警報時顯示溫度不能設定
  74.                 CountKey();//報警距離設置
  75.                 if(flag200ms)
  76.                 {
  77.                         flag200ms = 0;
  78.                         temp = ReadTemperature();//
  79.                         Temperature = temp * 6;//小數近似處理,采用中間變量temp是防止中斷導致最終溫度值異常
  80.                         if(Distance < Distance_Alarm)
  81.                         {
  82.                                 buzzer = 0;mod = 2;
  83.                         }
  84.                         else
  85.                         {
  86.                                 buzzer = 1;
  87.                                 if(!key1Mark)
  88.                                         mod = 0;
  89.                         }
  90.                 }                                                 //蜂鳴器產生300Hz頻率
  91.                 if(flag300ms)
  92.                 {
  93.                         flag300ms = 0;
  94.                         if(Distance < Distance_Alarm)
  95.                         {
  96.                                 buzzer = 1;
  97.                         }
  98.                 }
  99.         }
  100. }

  101. /*------------------------------------------------

  102. 顯示函數,用于動態掃描數碼管

  103. ------------------------------------------------*/
  104. void Display()
  105. {
  106.         static unsigned char i=0;

  107.         DataPort=0;   //清空數據,防止有交替重影
  108.         DUAN=1;     //段鎖存
  109.         DUAN=0;
  110.        
  111.         DataPort=WeiMa[i]; //取位碼
  112.         WEI=1;     //位鎖存
  113.         WEI=0;

  114.         if((i == 1) && (mod == 2))       
  115.         {
  116.                 DataPort = Table[TempData[i]] & 0xef;//溫度顯示點
  117.         }
  118.         else
  119.         {
  120.                 DataPort = Table[TempData[i]] ; //取顯示數據,段碼
  121.         }
  122.         DUAN=1;     //段鎖存
  123.         DUAN=0;
  124.        
  125.         i ++;
  126.         if(i == 4)
  127.                 i = 0;
  128. }
  129. //******************************************************************
  130. //20us短延時
  131. void delay_20us()
  132. {   
  133.         uchar bt;
  134.         for(bt=0;bt<20;bt++);
  135. }
  136. /*
  137. 處理需要顯示的數據
  138. 入口參數:ShowData
  139. */
  140. void CountDat(uint ShowData)
  141. {
  142.         EA=0;
  143.         TempData[0] =  ShowData / 1000 % 10;
  144.         TempData[1] =  ShowData / 100 % 10;
  145.         TempData[2] =  ShowData / 10 % 10;
  146.         TempData[3] =  ShowData % 10;
  147.         EA=1;
  148. }
  149. /*掃描K1 - K3*/
  150. void readkey()                 
  151. {
  152.         static uchar keycnt = 0;
  153.         uchar R0,R1;

  154.         P3 |= 0x07;                                                         //51單片機作為輸入時先置相應位位1
  155.         R0 = (P3 ^ 0x07) & 0x07; //將鍵值轉換成正邏輯
  156.         keycnt ++;          
  157.         if(R0)
  158.         {
  159.                 if(keycnt > 1) //用做延遲,根據MCU速度進行調整
  160.                 {
  161.                         keycnt = 0;
  162.                          key1 = R0;
  163.                 }
  164.                 else
  165.                 {
  166.                         key1 = key;
  167.                 }
  168.         }
  169.         else
  170.         {
  171.                 key1 = 0;                //無按鍵按下都為0
  172.                 keycnt = 0;
  173.         }  
  174.         R1 = key1;
  175.         key1 = key1 & (key ^ key1);//key^key1判斷鍵值有0變1,或1變0;再&key1若key1不為0則有按鍵按下(由0變1)
  176.         key = R1;               
  177. }
  178. /*讀取按鍵后,根據鍵值處理數據*/
  179. void CountKey()
  180. {
  181.         switch(key1)
  182.         {
  183.                 case 0x01:if(!key1Mark){mod = 1;key1Mark = 1;}
  184.                                                         else
  185.                                                         {
  186.                                                                 mod = 0;key1Mark = 0;
  187.                                                                 WriteBuf[0] = Distance_Alarm & 0xff; WriteBuf[1] = (Distance_Alarm >> 8) & 0xff;
  188.                                                                 ISP_IAP_sectorErase(0x2e00);//扇區擦除,一塊512字節         
  189.                                                     ISP_IAP_writeData(0x2ff0,WriteBuf,2);  //寫警報值到 EEPROM
  190.                                                         }
  191.                         break;
  192.                 case 0x02:if(mod == 1){Distance_Alarm += 5;if(Distance_Alarm > 400)Distance_Alarm=400;}                               
  193.                         break;
  194.                 case 0x04:if(mod == 1){Distance_Alarm -= 5;if(Distance_Alarm < 5)Distance_Alarm=5;}
  195.                         break;
  196.                 default : break;
  197.         }
  198.         switch(0)                 //數據顯示模式散轉
  199.         {
  200.                 case 0:DispData = Distance;        //正常默認下顯示測得的距離
  201.                         break;
  202.                 case 1:DispData =  Distance_Alarm;        //設置模式下顯示警報距離
  203.                         break;
  204.                 case 2:DispData = Temperature;        //警報下顯示當前溫度值
  205.                         break;
  206.                 default : break;
  207.         }
  208. }
  209. /*超聲波測距*/
  210. void CSBFunction()
  211. {
  212.         EA=0;
  213.         Trig=1;
  214.         delay_20us();
  215.         Trig=0;         //產生一個20us的脈沖,在Trig引腳
  216.         while(Echo==0); //等待Echo回波引腳變高電平,高電平持續的時間就是超聲波從發射到返回的時間
  217.         {
  218.           EX1=1;          //打開外部中斷
  219.                 TH1=0;          //定時器1清零
  220.           TL1=0;          //定時器1清零
  221.           TF1=0;         
  222.           TR1=1;          //啟動定時器1
  223.                 EA=1;
  224.         }
  225.         while(TH1 < 255);//等待測量的結果,周期65.535毫秒(可用中斷實現),在這段時間內等待外部中斷
  226.         {
  227.                 TR1=0;          //關閉定時器1
  228.           EX1=0;          //關閉外部中斷
  229.         }
  230. }
  231. /*------------------------------------------------
  232.             定時器初始化子程序
  233. ------------------------------------------------*/
  234. void Init_Timer0(void)
  235. {
  236.         TMOD |= 0x01;          //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響                     
  237.         TH0=(65536-2000)/256;                  //給定初值 2ms
  238.         TL0=(65536-2000)%256;
  239.         EA=1;            //總中斷打開
  240.         ET0=1;           //定時器中斷打開
  241.         TR0=1;           //定時器開關打開
  242. }
  243. /*------------------------------------------------
  244. ……………………

  245. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
eeprom超聲波.rar (57.28 KB, 下載次數: 41)





評分

參與人數 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:242685 發表于 2017-10-27 18:15 | 只看該作者
支持一下
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 美国av毛片 | 一区二区在线观看免费视频 | 国产视频二区在线观看 | 91麻豆精品国产91久久久久久久久 | 91av在线视频观看 | 欧美精品一区二区三区在线 | 久草在线在线精品观看 | 99免费在线视频 | av手机在线看| 久久久久9999亚洲精品 | 成人亚洲网| 久久国产精品久久久久 | 特一级毛片 | 日韩国产欧美 | 色婷婷精品 | 亚洲欧美中文日韩在线v日本 | 91久久精品国产91久久性色tv | 欧美日韩成人在线 | 久久精品国产精品青草 | 一区二区三区亚洲精品国 | 国产一级在线 | 国产在线一区二区 | 色吧久久 | 最新91在线 | 亚洲精品电影在线 | 国产高清视频在线观看 | 国产成人一区二区 | 日韩精品免费在线观看 | 99久久久久国产精品免费 | 久久成人免费视频 | 国产视频第一页 | 国产玖玖| 在线日韩中文字幕 | 亚洲欧美网站 | 狠狠躁天天躁夜夜躁婷婷老牛影视 | 欧美午夜精品久久久久久浪潮 | 福利精品 | 欧美视频区 | 国产黄色小视频在线观看 | www.888www看片 | 国产精品片aa在线观看 |