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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6032|回復: 5
收起左側

帶溫度補償的單片機超聲波測距儀原理圖PCB+源程序

[復制鏈接]
ID:413459 發表于 2018-10-22 19:12 | 顯示全部樓層 |閱讀模式
帶溫度補償的超聲波測距儀電路原理圖如下:
0.png

Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
0.png 0.png

元器件清單

帶溫度補償的超聲波測距儀
序號    元件名稱    型號與規格    單位    數量
1    電阻    1KΩ    只    6
        R19     10k    只    1
        R3      200K    只    1
        R4      20Ω    只    1
        R7~R12  R14  R17  R18  R20    470Ω    只    10
2    排針        排    1
3    電解電容    C3         3.3μF    只    1
        C4   1μF    只    1
        C7  10μF    只    1
4    電瓷電容    C1      0.24μF    只    1
        C2       330 pF    只    1
        C5   C6    30 pF    只    1
5    晶振    Y1         12MHz    只    1
6    三級管    VT1~VT4      9012    只    4
7    溫度傳感器    DX18320    塊    1
8    單片機    AT89S52    塊    1
9    紅外線接收芯片    CX20106A    塊    1
10    按鈕    S1~S3         只    3
11    發光二級管    VD1    只    1
12    數碼管    4位    只    1
13    超聲波發射    LS1    只    1
14    超聲波接收    LS2    只    1

單片機源程序如下:
  1. #include<reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. #define ulong unsigned long
  5. sbit we0=P2^0; //                數碼管位定義
  6. sbit we1=P2^1; //
  7. sbit we2=P2^2; //
  8. sbit we3=P2^3;
  9. sbit fasong=P1^0;                 //超生波發送接口
  10. sbit jieshou=P3^2;                 //超聲波接受接口
  11. sbit k1=P3^6;                         //開關鍵
  12. sbit k2=P3^7;                         //溫度距離顯示切換鍵
  13. sbit ds=P1^4;                         //溫度傳感數據接口
  14. uchar timers,mi,fenmi,limi,num2,num1,shi,ge,shifen,shengsu;
  15. bit flag,kaiflag,temflag;         //定義各種標志位
  16. ulong t,s;                                         //接收時間和距離
  17. uint temp,num;
  18. float n;                                         //18b20讀取數據時用
  19. uchar code table[]=                         //數碼管顯示編碼(不帶小數點and帶)
  20. {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
  21. 0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
  22. void init();                                 //聲明初始化函數
  23. void delay100us()                         //超聲波避盲區延時函數
  24. {
  25.         uchar i,j;
  26.         for(i=40;i>0;i--)
  27.                 for(j=248;j>0;j--);       
  28. }
  29. void delay(uchar a)                           //短暫延時函數(用于18B20)
  30. {
  31.          while(a>0)
  32.          a--;
  33. }
  34. void shijian(uint x)                        //一毫秒延時函數
  35. {
  36.         uint i,j;
  37.         for(i=x;i>0;i--)
  38.                  for(j=110;j>0;j--);
  39. }
  40. void reset()                                    //18B20復位
  41. {
  42.         ds=0;
  43.         delay(103);
  44.         ds=1;
  45.         delay(4);       
  46. }
  47. void write(uchar date)                    //18B20寫一字節數據
  48. {
  49.          uchar temp,i;
  50.          uint j;
  51.          temp=date;
  52.          for(i=0;i<8;i++)
  53.          {       
  54.                   temp=temp>>1;
  55.                  if(CY)                   //寫1
  56.                  {
  57.                          ds=0;
  58.                 j++;j++;
  59.                         ds=1;
  60.                         delay(8);
  61.                  }
  62.                  else
  63.                  {
  64.                          ds=0;
  65.                         delay(8);
  66.                         ds=1;
  67.                         j++;j++;
  68.                  }
  69.          }

  70. }
  71. uchar read()                                        //18B20讀一字節數據
  72. {
  73.         uchar j,dat;
  74.         for(j=0;j<8;j++)
  75.         {
  76.                 ds=0;
  77.                 dat>>=1;
  78.                 ds=1;
  79.                 delay(1);
  80.                 if(ds)
  81.                 dat|=0x80;
  82.                 delay(8);
  83.         }
  84.         return(dat);
  85. }
  86. uint get()                                                 //從溫度傳感器獲取數值
  87. {
  88.         uchar gao,di;
  89.         reset();
  90.         shijian(1);
  91.         write(0xcc);
  92.         write(0x44);

  93.         reset();
  94.         shijian(1);
  95.         write(0xcc);
  96.         write(0xbe);
  97.         di=read();
  98.         gao=read();
  99.         temp=gao<<8;
  100.         temp=temp|di;
  101.         n=temp*0.065+0.5;
  102.         temp=n*10;
  103.         return(temp);
  104. }
  105. void send()                                           //超聲波發送函數
  106. {
  107.         uchar i;
  108.         while(TF0==0)
  109.         {         we0=0;
  110.                  timers++;                          
  111.                  fasong=~fasong;
  112.                  for(i=12;i>0;i--);          //40hz延時
  113.                  if(timers==4)                  //連續發送兩個超聲波脈沖
  114.                  break;
  115.                
  116.         }
  117.         we0=1;                                          
  118.         timers=0;                                  //將發送次數歸零
  119.         TH0=0X00;                                  //定時器裝初值
  120.         TL0=0X32;                                  //裝0x32是因為發送時也占用了時間
  121.         TR0=1;                                          //打開計時器
  122.         EX0=1;                                          //打開外部中斷等待接收返回聲波
  123.         delay100us();                          //避盲延時
  124.         delay100us();
  125.         delay100us();
  126. //        delay100us();
  127. //        delay100us();
  128. }
  129. void keyscan()                                   //鍵盤掃描
  130. {
  131.         if(k1==0)                                   //開關鍵按下
  132.         {
  133.                 shijian(10);
  134.                 if(k1==0)
  135.                 kaiflag=~kaiflag;           //開關標志位取反
  136.                 while(k1==0);                   //等待按鍵釋放                   
  137.         }
  138.         if(k2==0)                                  //k2按下
  139.         {
  140.                 shijian(10);
  141.                 if(k2==0)
  142.                 temflag=~temflag;          //溫度距離標志位取反
  143.                 while(k2==0);                  //等待按鍵釋放
  144.         }
  145. }
  146. void temdisplay()                          //溫度顯示函數
  147. {
  148.         num=get();                                  //讀取當前溫度值
  149.         shi=num/100;                          //分離出十位值
  150.         ge=num%100/10;                          //分離出個位值
  151.         shifen=num%10;                          //分離出十分位值


  152.                 P0=table[shi];                  //十位顯示
  153.                 we1=0;
  154.                 we0=1;
  155.                 we2=1;
  156.                 we3=1;
  157.                 shijian(6);

  158.                 P0=table[ge+10];          //個位顯示
  159.                 we1=1;
  160.                 we0=1;
  161.                 we2=0;
  162.                 we3=1;
  163.                 shijian(6);

  164.                 P0=table[shifen];          //十分位顯示
  165.                 we3=0;
  166.                 we1=1;
  167.                 we0=1;
  168.                 we2=1;
  169.                 shijian(1);
  170. }
  171. void init()                                          //初始化函數
  172. {
  173.         TMOD=0x21;           //定時器1為8位自動重裝模式,
  174.                                    //定時器0為十六位計數器       
  175.         TH0=0X00;           //定時器0裝初值
  176.         TL0=0X32;          
  177.         TH1=0x00;           //定時器裝空值
  178.         TL1=0x00;          
  179.         TR1=0;                   //關閉顯示定時
  180.         TR0=0;                   //關閉定時器0計時
  181.         EA=1;                   //打開總中斷
  182.         ET0=1;                   //打開計時中斷
  183.         ET1=1;                   //打開定時器1中斷
  184.         EX0=1;                   //打開外部中斷
  185.         IT0=1;                   //外部中斷選擇下降沿觸發
  186.         P2=0xff;
  187.         P0=0xff;           //關閉數碼管段選
  188.         kaiflag=0;           //開標志位置0
  189.         temflag=0;           //溫度距離標志位置0
  190. }
  191. void main()                   //主函數
  192. {
  193.         init();                   //進行初始化
  194.         while(1)
  195.         {       
  196.                 keyscan();        //鍵盤掃描
  197.                 if((kaiflag==1)&&(temflag==1))//如果打開并且選擇測溫
  198.                 {
  199.                         temdisplay();                          //進行溫度顯示
  200.                         TR1=0;                                          //將定時器都關閉
  201.                     TR0=0;
  202.                         EX0=0;

  203.                 }
  204.                 if((kaiflag==1)&&(temflag==0)) //如果打開并選擇測距
  205.                 {       
  206.                         send();                                           //發送脈沖
  207.                         num=get();                                   //讀取溫度值          
  208.                         TR1=1;                                           //打開測距顯示中斷
  209.                 }
  210.                 if(kaiflag==0)                                   //如果處于關閉狀態
  211.                 {
  212.                         TR1=0;
  213.                         TR0=0;                                                //測距顯示關閉
  214.                         init();                                                //進行初始化
  215.                 }
  216.         }
  217. }
  218. /*******************對下面用到的中斷的解釋************
  219. 1.外部中斷0用來接收返回的脈沖,當接收到以后進行中斷處理,優先級最高;
  220. 2.定時器0用來計時,選擇的是十六位定時模式;用來計算超聲波脈沖
  221.   從發射到接受所用的時間。
  222. 3.定時器1用來作為測試距離的顯示定時。每中斷一次就掃描一位數碼管
  223. *********************************************************/
  224. void IN0() interrupt 0                                        //超聲波接收中斷(外部)
  225. {
  226.         TR0=0;                                                                //關閉設計時器
  227.         EX0=0;                                                                //停止接收返回脈沖
  228.     if(num<=50)                                          //根據當前溫度值來調整聲速
  229.         {
  230.                 shengsu=165;
  231.         }
  232.         else if(num<=100)
  233.         {
  234.                 shengsu=169;
  235.         }
  236.         else if(num<=200)
  237.         {
  238.                 shengsu=172;
  239.         }
  240.         else if(num<=300)
  241.         {
  242.                 shengsu=175;
  243.         }
  244.         else if(num<=500)
  245.         {
  246.                 shengsu=180;
  247.         }
  248.         t=TH0*256+TL0;                                //計算從發射到接收用時(單位us)
  249.         s=t*shengsu/10000;                                        //根據時間計算距離
  250.         mi=s/100;                                                        //分離出米
  251.         fenmi=s%100/10;                                                //……分米
  252.         limi=s%10;                                                        //……厘米
  253.         EX0=1;                                                //計算完畢允許接收下個脈沖
  254. }
  255. void timer0() interrupt 1
  256. {
  257.         TR0=0;
  258.         TH0=0;
  259.         TL0=0;

  260. }
  261. void timer1() interrupt 3                 //顯示測距距離中斷
  262. {
  263.         TH1=0x00;                                         //裝初值
  264.         TL1=0x00;
  265.         num1++;
  266.        
  267.         if(num1==5)                                         //如果經過1250us,顯示一位
  268.         {
  269.                
  270.                 num1=0;
  271.                 shijian(2);
  272.                 num2++;
  273.                 if(num2==4)
  274.                 num2=0;



  275.         }
  276.        
  277.         if(temflag==0)
  278.         {       
  279.                 if(num2==0)
  280.                 {
  281.                         P0=table[mi+10];
  282.                         we1=0;
  283.                         we0=1;
  284.                         we2=1;
  285.                         we3=1;
  286.                 }
  287.                 if(num2==2)
  288.                 {
  289.                         P0=table[fenmi];
  290.                         we1=1;
  291.                         we0=1;
  292.                         we2=0;
  293.                         we3=1;
  294.                 }
  295.                 if(num2==3)
  296.                 {
  297.                         P0=table[limi];
  298.                         we3=0;
  299.                         we1=1;
  300.                         we0=1;
  301.                         we2=1;
  302.                 }
  303.         }          

  304.                
  305. }
復制代碼

所有資料51hei提供下載:
Desktop.rar (1.56 MB, 下載次數: 97)


評分

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

查看全部評分

回復

使用道具 舉報

ID:439461 發表于 2018-12-9 21:29 | 顯示全部樓層
十分感謝你。這個真心不錯
回復

使用道具 舉報

ID:428027 發表于 2018-12-10 09:31 來自觸屏版 | 顯示全部樓層
請問:溫度補償是什么意思呀
回復

使用道具 舉報

ID:89286 發表于 2018-12-10 10:22 | 顯示全部樓層
thanks for sharing
回復

使用道具 舉報

ID:480175 發表于 2019-2-26 10:11 | 顯示全部樓層
番茄薯條 發表于 2018-12-10 09:31
請問:溫度補償是什么意思呀

環境溫度不同對應超聲波發射速度不同,通過溫度傳感器測出環境溫度,調用不同溫度下超聲波發射的速度實現溫度補償的功能。優點:測距更加準確,減小溫度變化對超聲波測距的影響。
回復

使用道具 舉報

ID:488725 發表于 2019-3-12 12:27 | 顯示全部樓層
能解釋下發送模塊的原理嗎
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产aⅴ精品一区二区 免费观看av | 亚洲视频在线播放 | 国产色| 国产成人免费视频 | 自拍偷拍小视频 | 欧美亚洲国产精品 | 国产精品国产成人国产三级 | 欧美精品一区三区 | 一区二区三区日本 | 中文字幕精 | 午夜a v电影 | 超碰日韩 | 国产伦一区二区三区四区 | 免费看a| 成人三级电影 | 中文字幕国 | 国产精品久久久久久久久免费丝袜 | 亚洲高清在线观看 | 成人免费视频久久 | 一级做a爰片性色毛片16 | 成人黄色三级毛片 | av超碰| 中文字幕国产一区 | 亚洲一区二区av | 一区天堂| 91社区视频 | 国产九九九 | 日本不卡一区二区三区在线观看 | 欧美久久一区二区 | 亚洲vs天堂 | 天堂成人国产精品一区 | 亚洲精品成人在线 | 欧美久久久久 | 亚洲精品国产综合区久久久久久久 | 人人爱干 | 色婷婷亚洲国产女人的天堂 | 欧美综合在线观看 | 四虎最新地址 | 中文字幕观看 | 天天摸天天干 | 国内精品伊人久久久久网站 |