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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于單片機+藍牙的DS18B20與HCSRO4源程序與詳細說明

[復制鏈接]
跳轉到指定樓層
樓主
基于DS18B20溫度傳感器的HC-SR04超聲波模塊與溫度報警的藍牙連接
一:前言:
這個小項目算是我硬件學習的入門吧,我把其中的問題與大家分享一下,同樣作為入門的一員
功能:(1)基于溫度值算出聲速從而計算障礙物的距離
       (2)設定額定溫度,超過額定溫度五次發出警告

效果圖:

發送“99”后,重置                           輸入合法溫度值后,Distance為0是因為前方無障礙

二:項目的簡單介紹
這個工程總共分為四個模塊:顯示模塊1602;溫度模塊DS18B20;;超聲波模塊HC- SR04;
藍牙模塊HC-06;
   顯示模塊1602,大家應該都比較清晰,這里不做過多描述。
   附錄代碼:
  1. #include<reg52.h>   // 由于液晶我們這里只寫不讀,所以RW直接接地
  2. sbit dula = P2^;
  3. sbit wela =P2^;     // 倆鎖存器,觀看各自原理圖是否有
  4. sbit RS = P3^;
  5. sbit LCDEN =P3^;    // RS與lcden接口
  6. void writeComm(ucharcomm)  // 寫指令
  7. {
  8.     RS = 0;
  9.     P0 = comm;
  10.     LCDEN = 1;
  11.     delayMs(1);
  12.     LCDEN = 0;
  13.     delayMs(1);
  14. }
  15.                               
  16. void writeData(uchardat)   //寫數據:RS=1, RW=0;
  17. {
  18.     RS = 1;
  19.     P0 = dat;
  20.     LCDEN = 1;
  21.     delayMs(1);
  22.     LCDEN = 0;
  23.     delayMs(1);
  24. }
  25. void init()
  26. {
  27.     dula = wela = 0;
  28.     writeComm(0x38);
  29.     writeComm(0x0c);
  30.     writeComm(0x06);
  31.     writeComm(0x01);
  32.    
  33. }
復制代碼
溫度模塊:DS18B20模塊,不過多描述,想要說一下負溫度的計算與讀取,網上資料也比較多一些。首先要了解,LS(低字節)的高四位 和 MS(高字節)的低四位共8個字節構成了實際的一個帶符號位的字節數據可以表示18B20的溫度范圍。MS的高四位為符號為的擴展,當溫度值為正時MS高5位全為0,溫度值為負時全為1。
第一種:讀取的溫度為負數時,MS高五位全1,我們已經得到十六位數據value,
如果value<0x0fff,則為正,反之為負數
第二種:Hvalue&0x1f==1,為負溫度,Hvalue為MS;
代碼如下:
  1. sbit ds = P2^;
  2. uintdealcount=0;
  3.      // 一次計算超出額定溫度的次數,初始化為0,與藍牙模塊相關,超過額定溫度5次,向手機發出告警信號
  4.     Uint temp_flag     // 設置溫度符號的判斷符
  5. void dsInit()
  6. {

  7.     unsigned int i;
  8.     ds = 0;
  9.     i = 100;
  10.     while(i>0) i--;
  11.     ds = 1;
  12.     i = 4;
  13.     while(i>0) i--;
  14. }

  15. void dsWait()
  16. {
  17.     unsigned int i;
  18.     while(ds);
  19.     while(~ds);
  20.     i = 4;
  21.     while(i > 0)
  22.         i--;
  23. }


  24. bitreadBit()              //讀一位
  25. {
  26.     unsigned int i;
  27.     bit b;
  28.     ds = 0;
  29.     i++;
  30.     ds = 1;
  31.     i++;
  32.     i++;
  33.     b = ds;
  34.     i = 8;
  35.     while(i>0) i--;
  36.     return b;
  37. }

  38. unsigned char readByte()              //讀一字節
  39. {
  40.     unsigned int i;
  41.     unsigned char j, dat;
  42.     dat = 0;
  43.     for(i=0; i<8; i++)
  44.     {
  45.         j = readBit();

  46.         dat = (j << 7) | (dat >>1);
  47.     }
  48.     return dat;
  49. }


  50. voidwriteByte(unsigned char dat)
  51. {
  52.     unsigned int i;
  53.     unsigned char j;
  54.     bit b;
  55.     for(j = 0; j < 8; j++)
  56.     {
  57.         b = dat & 0x01;                          //一位一位判別0,1
  58.         dat >>= 1;                              // dat右移一位

  59.         if(b)                                    //寫0,寫1操作時序
  60.         {
  61.             ds = 0;
  62.             i++;
  63.             i++;
  64.             ds = 1;
  65.             i = 8;
  66.             while(i>0) i--;
  67.         }
  68.         else
  69.         {
  70.             ds = 0;
  71.             i = 8;
  72.             while(i>0) i--;
  73.             ds = 1;
  74.             i++;
  75.             i++;
  76.         }
  77.     }
  78. }



  79. intgetTmpValue()
  80. {
  81.     unsigned int tmpvalue;
  82.     int value;
  83.     float t;
  84.     unsigned char low, high;
  85.     sendReadCmd();
  86.     low = readByte();
  87.     high = readByte();
  88.     tmpvalue = high;
  89.     tmpvalue <<= 8;
  90.     tmpvalue |= low;
  91.    if(tmpvalue<0x0fff)
  92. {

  93.     value=tmpvalue;  
  94.     temp_flag=0;       //0為正

  95. }
  96. else{

  97.      value=~tmpvalue+1;
  98.      temp_flag=1;

  99. }
  100.     t = value * 0.0625;
  101.     value = t * 100 + (value > 0 ? 0.5 :-0.5);     
  102.     return value;
  103. }



  104. voidsendChangeCmd()  // 初始化
  105. {
  106.     dsInit();
  107.     dsWait();
  108.     delayMs(1);
  109.     writeByte(0xcc);
  110.     writeByte(0x44);
  111. }

  112. voidsendReadCmd()   // 讀溫度
  113. {
  114.     dsInit();
  115.     dsWait();
  116.     delayMs(1);
  117.     writeByte(0xcc);
  118.     writeByte(0xbe);
  119. }
復制代碼

超聲波模塊:HC-SR04模塊
具體可以看模塊說明書
附錄代碼,主要看注釋
  1. sbit input=P1^ ;                           //Echo引腳
  2. sbit output=P1^ ;                         //Trig引腳
  3. uint count,distance;                       // distance距離,count計算多少ms
  4. void HC_prepare()                        //模塊的準備工作
  5. {

  6.    output=1;                             
  7.    input=1;
  8.    count=0;
  9.    distance=0;

  10. }

  11. void trig_init()                           //Trig引腳發出觸發信號              
  12. {

  13.    output=1;
  14.    delayUs();
  15.    output=0;


  16. }

  17. void measure(int temp)                //根據溫度測距,算出大概的聲速
  18. {
  19.    uint h,l;
  20.    uint y;
  21.    TR0=1;                         //打開定時器0
  22.    while(input)
  23.     {
  24.        ;

  25.     }
  26.    TR0=0;                         //Exho引腳返回高電平持續的時間
  27.    l=TL0;                         //低四位賦值
  28.    h=TH0;                        //高四位賦值
  29.    y=(h<<8)+l;
  30.    y=y-0xfc66;                   //減去定時期初值
  31.    distance=y+1000*count;        //得到ms
  32.    TL0=0x66;
  33.    TH0=0xfc;                    //定時器重新賦值
  34.    delayMs(10);
  35.    distance=(331.45+0.61*temp)*distance/20000;     //根據不同需求修改


  36. }


  37. void display(int v)             // v為DS18B20已經測出的value
  38. {
  39.    unsigned char b,c,d,e;
  40.    unsigned char count;
  41.    unsigned char datas[] = {0, 0, 0, 0, 0};
  42.    unsigned int tmp v;
  43. int xz_temp;                              
  44. //設置倆位數的溫度(去掉小數后測量的溫度)
  45.    datas[0] = tmp / 10000;                 
  46.    datas[1] = tmp % 10000 / 1000;
  47.    datas[2] = tmp % 1000 / 100;
  48.    datas[3] = tmp % 100 / 10;
  49.    datas[4] = tmp % 10;
  50.    xz_temp=10*datas[1]+datas[2];      
  51.    if(xz_temp>set_temp)
  52.        dealcount++;                  //溫度大于設置的預警溫度,進行一次加一
  53.    writeComm(0x80+0x40);            //液晶地址為第二行
  54.    uart_sendstr(table1);               
  55.    delayMs(15);                      //延時,可能發送不完全,可以自己調整
  56.    if (temp_flag==1)                  //判斷符號位
  57.     {
  58.        writeData('-');                  //液晶寫數據
  59.        uart_senddata('-');              //藍牙發送數據,
  60.     }
  61.    else
  62.     {
  63.        writeData('+');
  64.        uart_senddata('+');
  65.     }
  66.    if(datas[0] != 0)
  67.     {
  68.        writeData('0'+datas[0]);
  69.        uart_senddata(datas[0]+0x30);
  70.     }
  71.    for(count = 1; count != 5; count++)
  72.     {
  73.        writeData('0'+datas[count]);
  74.        uart_senddata(datas[count]+0x30);     
  75.        if(count == 2)
  76.        {
  77.            writeData('.');
  78.            uart_senddata('.');
  79.        }
  80.     }
  81.    uart_senddata(0x20);
  82.    uart_senddata(0x20);                     //0x20為空,0x2e為‘.’
  83.    writeComm(0xc0+8);                    
  84.    b=distance/1000;   
  85.    c=distance/100%10;
  86.    d=distance/10%10;
  87.    e=distance%10;
  88.    uart_sendstr(table2);
  89.    delayMs(15);                           //延時
  90.    writeData('0'+b);
  91.    uart_senddata(b+0x30);
  92.    writeData('0'+c);
  93.    uart_senddata(c+0x30);
  94.    writeData('0'+d);
  95.    uart_senddata(d+0x30);
  96.    writeData('.');
  97.    uart_senddata('.');
  98.    writeData('0'+e);
  99.    uart_senddata(e+0x30);
  100.    writeData('c');
  101.    uart_senddata('c');
  102.    writeData('m');
  103.    uart_senddata('m');
  104.    delayMs(15);
  105. }
復制代碼
其中要了解的基礎知識點:
(1)‘\0’與‘0’   
1)’\0’,就是空字符,代表字符串結束的標志。對應的ASCLL碼是0(NULL)
2)’0’,字符常量,表示字符0,對應的ASCLL碼是48,也就是0x30

(2)單片機內不同進制數計算
  運算時機器都是轉換為二進制計算,所以書寫沒有必要轉換為統一的進制表達


藍牙模塊:HC-06
主要介紹見代碼,AT指令集可以查使用手冊
  1. void init_uart_and_HC()              // 串口與HC模塊的初始化
  2. {

  3.    TMOD=0X21;                  //設置定時器模式
  4.    PCON=0X00;                  //設置電源寄存管理器
  5.    SCON=0x50;                  //串行口控制管理器
  6.     TH1=0XFD;                  
  7. TL1=0XFD;
  8. //設定9600波特率
  9.    TH0=0XFC;
  10. TL0=0X66;
  11. //對HC-SR04所用定時器賦初值

  12.    TR1=1;
  13.    ET0=1;
  14.    EA=1;
  15.    ES=1;

  16. }



  17. void uart_senddata(char dat)           //  串口發送單位數據
  18. {
  19.    ES=0;
  20.    SBUF=dat;
  21.    while(!TI);
  22.    TI=0;
  23.    ES=1;

  24. }

  25. void uart_sendstr(char *p)           //     串口發送字符串
  26. {
  27.    ES=0;
  28.    do
  29.     {

  30.        uart_senddata(*p);


  31.     }
  32.    while(*p++!='\0');
  33.    ES=1;
  34. }
  35. void delayUs()
  36. {
  37.    _nop_();
  38. }

  39. void delayMs(uint a)
  40. {
  41.    uint i, j;
  42.    for(i = a; i > 0; i--)
  43.        for(j = 110; j > 0; j--);
  44. }
復制代碼
主函數:
  1. #include <reg52.H>
  2. #include <intrins.H>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. uchar flag=0,mode;                 //flag表示輸入合法,mode表示發出指令
  6. uchar b[]="ERROR";                 //超出額定溫度五次
  7. uchar c[]="OKreset";                //輸入“99”后發送
  8. uchar receive_com[2];              //接收字符組
  9. uchar index=0;                    //接收字符組的索引
  10. uchar init_temp[]="Set yourtemp:";
  11. uchar table1[]="temp:  ";
  12. uchar table2[]="Distance:";
  13. int set_temp;
  14. void main()
  15. {
  16.    int temp;
  17.    init();
  18.    init_uart_and_HC();
  19.    writeComm(0x80);
  20.    sendChangeCmd();
  21.    if(flag==0)
  22.     {
  23.        uart_sendstr(init_temp);
  24.        while(!mode)  
  25.        {
  26.            ;                                 
  27. //   表示人為有響應,只有藍牙接收到數據才會啟動
  28.        }
  29.     }
  30.    while(flag==1)                    //  輸入合法的溫度執行
  31.     {
  32.        writeString(table1,7);
  33.        writeString(table2,9);
  34.        HC_prepare();
  35.        temp=getTmpValue();
  36.        trig_init();
  37.        while(input==0)
  38.        {
  39.            ;
  40.        }
  41.        measure(temp);
  42.        display(temp);
  43.        uart_senddata('\r');
  44.        uart_senddata('\n');
  45.        if(dealcount==5)
  46.        {
  47.            uart_sendstr(b);
  48.            BEEP();                    //延時2.5s,這里可以自己修改
  49.            dealcount=0;
  50.        }
  51.        sendChangeCmd();
  52.        HC_prepare();


  53.     }
  54. mode=0;                 //若跳出while循環,說明接收到了,重置信號
  55. dealcount=0;            // 將超出額定溫度的計數置0

  56. }




  57. void t0() interrupt 1
  58. {
  59.    TL0 = 0x66;
  60.    TH0 = 0xfc;
  61.    count++;               //溢出為1ms
  62.    if(count == 18)//超聲波回聲脈寬最多18ms
  63.     {
  64.        TR0 =0;
  65.        TL0 = 0x66;
  66.        TH0 = 0xfc;
  67.        count = 0;
  68.     }

  69. }

  70. void ser() interrupt 4
  71. {

  72.    RI=0;
  73.    receive_com[index]=SBUF;     
  74.    index++;
  75.   if(index==2)                      //整點溫度值輸入,當為2位時進入執行
  76.     {
  77.        index=0;                    //重置index

  78.        set_temp=(receive_com[0]-0x30)*10+receive_com[1]-0x30;   
  79. //將字符計算為整數值
  80.        if(set_temp==99)            //99為重置值
  81.        {

  82.            flag=0;               
  83.            uart_sendstr(&c);
  84.            uart_senddata('\r');
  85.            uart_senddata('\n');
  86. //發送回車換行
  87.        }
  88.        if(set_temp!=99)                //正常輸入時
  89.        {
  90.            uart_sendstr(receive_com);
  91.            uart_senddata('\r');
  92.            uart_senddata('\n');
  93.            flag=1;                   //置flag為1

  94.        }


  95.        mode=1;                   //mode置1,表示有輸入,表示人為響應
  96.     }


  97. }
復制代碼

整體思想:
(1)     mode,flag為主要參數,mode決定是否進入運行,是否響應
(2)     對輸送數據的發送接收要清晰

可以改進的幾點:
(1)     設定溫度可以到小數點后倆位,提高精確度,只需要加一個判斷小數點的函數
(2)     可以將功能提高一些,比如判斷距離或其他

評分

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

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成人综合久久 | 国产精品污www一区二区三区 | 亚洲欧美一区二区三区在线 | 久久黄色精品视频 | 精品一二 | 国产精品国产精品国产专区不卡 | 精品久久久久久久久久久久 | 亚洲精品视频在线观看视频 | 国产精品3区 | 亚洲午夜视频 | 在线啊v | 国产激情在线看 | 精品欧美一区二区三区精品久久 | 亚洲a视 | 欧美日韩国产一区二区三区 | 亚洲久久一区 | 日本久久黄色 | 亚洲一区在线播放 | 成人在线视频免费观看 | 国产色网站 | 91日b| 久草新在线| 成人一区av偷拍 | 免费人成在线观看网站 | 91久久久久久久久久久久久 | 国产一区二区三区四区五区加勒比 | 天天射色综合 | 最近中文字幕第一页 | 午夜电影福利 | 国产精品mv在线观看 | 亚洲国产精品一区二区三区 | 一区二区亚洲 | 视频一区二区在线 | 欧区一欧区二欧区三免费 | 国产日韩欧美精品一区二区三区 | 91精品国产综合久久久久蜜臀 | 久久99精品视频 | 在线成人www免费观看视频 | 日韩精品一区二区三区视频播放 | 韩日三级 | 在线观看国产视频 |