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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

帶詳細注釋的單片機超聲波測距源程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:424544 發表于 2018-11-11 16:11 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
超聲波單片機源程序如下:
  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. ------------------------------------------------*/
  246. void Timer0_isr(void) interrupt 1
  247. {
  248.         static unsigned char Cnt200ms,Cnt300ms;
  249.         TH0=(65536-2000)/256;                  //重新賦值 2ms
  250.         TL0=(65536-2000)%256;

  251.         Display();       // 調用數碼管掃描
  252.         Cnt200ms ++;
  253.         if(Cnt200ms == 100)
  254.         {
  255.                 Cnt200ms = 0;
  256.                 flag200ms = 1;
  257.                 Cnt300ms ++;
  258.                 if(Cnt300ms == 3)
  259.                 {
  260.                         Cnt300ms = 0;
  261.                         flag300ms = 1;       
  262.                 }
  263.         }
  264. }
  265. //***************************************************************
  266. //外部中斷1,用做判斷回波電平,低電平引發中斷,得到高電平的持續時間
  267. INT1_()  interrupt 2   // 外部中斷
  268. {   
  269.         EchoTimeH = TH1;    //取出定時器的值
  270.         EchoTimeL = TL1;    //取出定時器的值
  271.         succeed_flag = 1;  //置成功測量的標志
  272.         EX1=0;             //關閉外部中斷
  273. }
復制代碼

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


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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩超碰| 日本成人在线网址 | 国产精品久久一区二区三区 | 亚洲欧美中文日韩在线v日本 | 一区二区国产在线观看 | 国产精品我不卡 | 欧美综合一区二区 | 亚洲高清在线观看 | 免费观看毛片 | 久久久国产一区二区三区 | com.色.www在线观看 | 久久99精品久久久久久秒播九色 | 久久久www成人免费精品 | 91久久精品国产 | 中文成人在线 | 久久九| 综合久久久久久久 | 亚洲成人久久久 | aaaaa毛片| 久久综合婷婷 | 国产免费一区二区三区 | 亚洲免费三级 | 久久99视频这里只有精品 | 久久久久久91 | 黄色大片免费看 | 999视频| 一级黄色片日本 | 国产片侵犯亲女视频播放 | 超碰97人人人人人蜜桃 | 欧美涩| 在线视频亚洲 | 日韩精品一区二区三区第95 | 免费99精品国产自在在线 | 国产视频1区 | h片免费看| 欧美一级在线观看 | 日韩精品在线网站 | 草久视频 | 中文成人无字幕乱码精品 | 精品欧美一区二区三区久久久 | 求个av网址|