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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

用DS18B20采集溫度和用單片機T0端口作時鐘,并在LCD1602上顯示

[復制鏈接]
跳轉到指定樓層
樓主
自己做的,有不足的地方請指出,一起學習進步!
這個設計由單片機最小系統、溫度傳感模塊 (DS18B20)、顯示模塊(LCD1602)、按鍵模塊和聲光報警模塊組成。
功能:①顯示 時—分—秒和實時溫度;②可以通過按鍵調整顯示時間,還可以調整聲光報警(7秒后自動關閉)的時間,并且還可以手動關閉聲光報警

電路圖和系統各框圖:



單片機程序:
  1. #include <reg51.h>
  2. #include <intrins.h>                           //包含_nop_空函數指令的頭文件
  3. #include <stdio.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define out P0
  7. uchar date[20];                           //存放溫度值
  8. sbit RS=P3^5;                          // 寄存器選擇(1——數據寄存器;0——命令/狀態寄存器)
  9. sbit RW=P3^6;                          // 讀/寫操作選擇(1——讀;0——寫)
  10. sbit E=P3^4;                          // 使能信號

  11. sbit voise=P2^3;            //蜂鳴器鏈接口
  12. sbit beeled=P1^7;                //LED燈接口

  13. sbit CON  = P3^0;
  14. sbit UP   = P3^1;
  15. sbit DOWN = P3^2;
  16. sbit START= P3^3;

  17. sbit ds = P2^2;                         //溫度傳感器的輸入/輸出引腳

  18. void keyScan();         //按鍵調時間
  19. void keyclockdown();        //按下按鍵關閉鬧鐘

  20. void init();                    //定時器T0的初始化
  21. void TIME();                        //實現時間變化

  22. void lcd_initial();     //lcd1602初始化
  23. void check_busy();      //檢查忙碌標志位
  24. void write_command(uchar com);   //寫命令
  25. void wtite_data(uchar  dat);         //寫數據
  26. void string(uchar ad,uchar *s);         //顯示字符串
  27. uchar dis[ ]={0x30,0x38,0x2d,0x35,0x39,0x2d,0x35,0x37,'\0'};                //dis[]={0,8,-,5,9,-,5,7}

  28. void delayMs(uint a);
  29. void delay(uint);

  30. void bee();                         //蜂鳴器
  31. uchar flag;

  32. uchar num;
  33. uchar over=0;
  34. void aoto();                         //7s后自動關閉鬧鈴

  35. uchar a=0x30,b=0x38,c=0x30,d=0x30,e=0x30,f=0x30;

  36. void dsInit();                                             //DS18B20復位,初始化函數
  37. void dsWait();
  38. bit readBit();                                             //讀一位數據函數
  39. unsigned char readByte();                         //讀一個字節數據函數
  40. void writeByte(unsigned char dat);             //向DS18B20寫一個字節數據函數
  41. void sendChangeCmd();                                         //DS18B20開始獲取溫度并轉換
  42. void sendReadCmd();                                                 //讀取寄存器中存儲的溫度數據
  43. int getTmpValue();                                                 //得到溫度

  44. //*************************************************************
  45. void main()
  46. {
  47.         float temp=0.0;
  48.         lcd_initial ();                                          //液晶顯示初始化
  49.         init();                                                           //定時器的初始化
  50.         while(1)
  51.         {
  52.                         bee();
  53.                         keyScan();                                  //按鍵調時間
  54.                         keyclockdown();                          //按下按鍵關閉鬧鐘
  55.                         aoto();
  56.                         delay(200);
  57.                         string(0x80,"TIME:");
  58.                         delay(200);
  59.                         string(0xcb,"^C");
  60.                         string(0x86,dis);
  61.                         delay(200);
  62.                         temp=getTmpValue()/100.0;
  63.                         sendChangeCmd();
  64.                         sprintf(date,"TEMP: %0.2f",temp);
  65.                         string(0xc0,date);
  66.                         delay(200);
  67.         }


  68. }
  69. //**************************************************************
  70. //延遲函數
  71. void delayMs(uint a)
  72. {
  73.     uint i, j;
  74.     for(i = a; i > 0; i--)
  75.         for(j = 100; j > 0; j--);
  76. }

  77. void delay (uint j)                         //延遲
  78. {
  79.         uchar i=10;
  80.         for(;j>0;j--)
  81.         {
  82.                 while(--i);
  83.                 i=10;
  84.                 while(--i);
  85.                 i=10;
  86.         
  87.         }
  88. }

  89. //********************************************************
  90. void init()                                          //定時器的初始化
  91. {
  92.         TMOD=0x01;                                  //定時器T0的方式1
  93.         TH0=(65536-50000)/256;          //50ms
  94.         TL0=(65536-50000)%256;
  95.         EA=1;                                          //總中斷允許
  96.         ET0=1;                                          //啟動定時器T0中斷
  97.         TR0=1;                                          //啟動定時器T0
  98. }

  99. void timer0() interrupt 1           //T0中斷程序
  100. {
  101.         TH0=(65536-50000)/256;          //50ms
  102.         TL0=(65536-50000)%256;
  103.         num++ ;
  104.         TIME();                                          //實現時間變化
  105. }

  106. //***********************************************************
  107. void lcd_initial ()                        //液晶顯示初始化
  108. {
  109.         write_command(0x38);        //寫入命令0x38;8位2行顯示,5×7點陣字符
  110.         _nop_();
  111.         write_command(0x0c);            //寫入命令0x0c;整體顯示,光標關閉,無閃爍
  112.          _nop_();
  113.         write_command(0x06);                //寫入命令0x05;光標右移
  114.         _nop_();
  115.         write_command(0x01);                //寫入命令0x01;清屏
  116.         delay(1);
  117. }

  118. void check_busy ()                //檢查忙標志
  119. {                                                
  120.         uchar dt;                        //dt變量單元 ,忙狀態標志 0:不忙,0x80:忙
  121.         do
  122.         {
  123.                 dt=0xff;                  // 先往數據端口賦高電平,便于讀數據
  124.                 E=0;
  125.                 RS=0;
  126.                 RW=1;          //讀
  127.                 E=1;           // 數據端口讀寫使能
  128.                 dt=out;           // 讀數據端口的值
  129.         }while(dt&0x80);         // 如果忙位BF為1,就一直讀端口數據,直到為0才退出忙判斷。
  130.                                                   // BF:忙標志位,為數據端口的BIT7位。所以為0x80。
  131.         E=0;
  132. }

  133. void write_command (uchar com)           //寫命令
  134. {
  135.         check_busy();
  136.         E=0;                                                   //RS=E=0;才可以寫入命令
  137.         RS=0;
  138.         RW=0;
  139.         out=com;
  140.         E=1;
  141.         _nop_();        //空操作1個機械周期
  142.         E=0;
  143.         delay(1);
  144. }

  145. void write_data (uchar dat)                //寫數據
  146. {
  147.         check_busy();                                //檢測忙標志位BF=1則等待,BF=0則可對LCD寫入
  148.         E=0;                                                //寫數據時,E為正脈沖,所以E置0
  149.         RS=1;                                                //RS=1,RW=1時,才可以寫入數據
  150.         RW=0;
  151.         out=dat;                                        //將數據dat從P0口輸出,即寫入LCD
  152.         E=1;                                            //E產生正跳變
  153.         _nop_();                                        //空操作1個機械周期
  154.         E=0;                                                //E由高電平變低電平,寫操作結束
  155.         delay(1);
  156. }

  157. void string(uchar ad,uchar *s)
  158. {
  159.         write_command(ad);
  160.         while(*s>0)
  161.         {
  162.                 write_data(*s++);           //輸出字符傳,指針加1
  163.                 delay(1);
  164.         }
  165. }

  166. //*****************************************************
  167. void TIME()                                     //實現時分秒變化
  168. {
  169.         if(num==20)
  170.                 {
  171.                         num=0;
  172.                         over++;
  173.                         dis[7]++;
  174.                         if(dis[7]>0x39)                  //秒
  175.                         {
  176.                                 dis[7]=0x30;
  177.                                 dis[6]++;
  178.                          }
  179.                         if(dis[6]==0x36)         
  180.                         {
  181.                                 dis[6]=0x30;
  182.                                 dis[4]++;
  183.                         }
  184.                         if(dis[4]>0x39)                   //分
  185.                         {
  186.                                 dis[4]=0x30;
  187.                                 dis[3]++;
  188.                                 }
  189.                         if(dis[3]==0x36)
  190.                         {
  191.                                 dis[3]=0x30;
  192.                                 dis[1]++;
  193.                          }
  194.                         if(dis[1]>0x39)                //時
  195.                         {
  196.                                 dis[1]=0x30;
  197.                                 dis[0]++;
  198.                          }
  199.                         if(dis[0]==0x32)
  200.                         {
  201.                                 if(dis[1]>0x33)
  202.                                 {
  203.                                         dis[0]=0x30;
  204.                                         dis[1]=0x30;
  205.                                 }        
  206.                         }
  207.         }
  208. }

  209. //*******************************************************
  210. //掃描鍵盤程序
  211. void keyScan()
  212. {
  213.         static uchar key;
  214.         if(!CON){ while(!CON);key++;}
  215.         if(key)
  216.         {
  217.                 TR0=0;          //時間先停下,再調整
  218.                 P1=~(key%7);    //指示燈
  219.                 switch(key%7)
  220.                 {
  221.                         case 6:        if(!UP)                                                                  //秒的個位
  222.                                         {
  223.                                                 while(!UP);        
  224.                                                 dis[7]++;
  225.                                                 if(dis[7]>0x39) dis[7]=0x30;
  226.                                         }
  227.                                         if(!DOWN)
  228.                                         {
  229.                                                 while(!DOWN);
  230.                                                 dis[7]--;
  231.                                                 if(dis[7]<0x30) dis[7]=0x39;
  232.                                         }  
  233.                                         break;           
  234.                         case 5:        if(!UP)                                                                           //秒的十位
  235.                                         {
  236.                                                 while(!UP);        
  237.                                                 dis[6]++;
  238.                                                 if(dis[6]>0x35) dis[6]=0x30;
  239.                                         }
  240.                                         if(!DOWN)
  241.                                         {
  242.                                                 while(!DOWN);
  243.                                                 dis[6]--;
  244.                                                 if(dis[6]<0x30) dis[6]=0x35;
  245.                                         }           
  246.                                         break;
  247.                         case 4:        if(!UP)                                                                           //分的個位
  248.                                         {
  249.                                                 while(!UP);        
  250.                                                 dis[4]++;
  251.                                                 if(dis[4]>0x39) dis[4]=0x30;
  252.                                         }
  253.                                         if(!DOWN)
  254.                                         {
  255.                                                 while(!DOWN);
  256.                                                 dis[4]--;
  257.                                                 if(dis[4]<0x30) dis[4]=0x39;
  258.                                         }           
  259.                                         break;
  260.                         case 3:        if(!UP)                                                                                //分的十位
  261.                                         {
  262.                                                 while(!UP);        
  263.                                                 dis[3]++;
  264.                                                 if(dis[3]>0x35) dis[3]=0x30;
  265.                                         }
  266.                                         if(!DOWN)
  267.                                         {
  268.                                                 while(!DOWN);
  269.                                                 dis[3]--;
  270.                                                 if(dis[3]<0x30) dis[3]=0x35;
  271.                                                 }           
  272.                                                 break;        
  273.                         case 2:        if(!UP)                                                                          // 時的個位
  274.                                         {
  275.                                                 while(!UP);        
  276.                                                 dis[1]++;
  277.                                                 if(dis[0]==0x30||dis[0]==0x31)
  278.                                                 {
  279.                                                         if(dis[1]>0x39) dis[1]=0x30;
  280.                                                 }
  281.                                                 if(dis[0]==0x32)
  282.                                                 {
  283.                                                         if(dis[1]>0x33)         dis[1]=0x30;
  284.                                                 }
  285.                                         }
  286.                                         if(!DOWN)
  287.                                         {
  288.                                                 while(!DOWN);
  289.                                                 dis[1]--;
  290.                                                 if(dis[0]==0x30||dis[0]==0x31)
  291.                                                 {
  292.                                                         if(dis[1]<0x30) dis[1]=0x39;
  293.                                                 }
  294.                                                 if(dis[0]==0x32)
  295.                                                 {
  296.                                                         if(dis[1]<0x30)         dis[1]=0x33;
  297.                                                 }

  298.                                         }           
  299.                                                 break;
  300.                         case 1:        if(!UP)                                                                        //時的十位
  301.                                                 {
  302.                                                         while(!UP);        
  303.                                                         dis[0]++;
  304.                                                         if(dis[0]>0x32) dis[0]=0x30;
  305.                                                 }
  306.                                                 if(!DOWN)
  307.                                                 {
  308.                                                         while(!DOWN);
  309.                                                         dis[0]--;
  310.                                                         if(dis[0]<0x30) dis[0]=0x32;
  311.                                                 }           
  312.                                                 break;        
  313.                 }               
  314.         }
  315.         if(!START)
  316.         {
  317.                 while(!START);
  318.                 TR0=1;
  319.                 key=0;
  320.                 P0=0xff;
  321.         }
  322. }

  323. //*******************************************************************************蜂鳴器
  324. void bee()
  325. {
  326.         keyclockdown();
  327.         if(dis[0]==a&&dis[1]==0x38&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)          //8點
  328.         {
  329.                 flag=1;
  330.         }
  331.         if(dis[0]==a&&dis[1]==0x39&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)          //9點
  332.         {
  333.                 flag=1;
  334.         }
  335.         if(dis[0]==0x31&&dis[1]==0x30&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)          //10點
  336.         {
  337.                 flag=1;
  338.         }
  339.         if(dis[0]==0x31&&dis[1]==0x31&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)          // 11點
  340.         {
  341.                 flag=1;
  342.         }
  343.         if(dis[0]==0x31&&dis[1]==0x32&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)           // 12點
  344.         {
  345.                 flag=1;
  346.         }
  347.         if(dis[0]==0x31&&dis[1]==0x33&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)                //13點
  348.         {
  349.                 flag=1;
  350.         }
  351.         if(dis[0]==0x31&&dis[1]==0x34&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)                 //14點
  352.         {
  353.                 flag=1;
  354.         }
  355.         if(dis[0]==0x31&&dis[1]==0x35&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)                 //15點
  356.         {
  357.                 flag=1;
  358.         }if(dis[0]==0x31&&dis[1]==0x36&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)                //16點
  359.         {
  360.                 flag=1;
  361.         }if(dis[0]==0x31&&dis[1]==0x37&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)                 //17點
  362.         {
  363.                 flag=1;
  364.         }
  365.         if(dis[0]==0x31&&dis[1]==0x38&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)                 //18點
  366.         {
  367.                 flag=1;
  368.         }
  369.         if(dis[0]==0x31&&dis[1]==0x39&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)                 //19點
  370.         {
  371.                 flag=1;
  372.         }
  373.         if(dis[0]==0x32&&dis[1]==0x30&&dis[3]==c&&dis[4]==d&&dis[6]==e&&dis[7]==f)                  //20點
  374.         {
  375.                 flag=1;
  376.         }

  377.         if(flag==1)
  378.                 {voise=0;beeled=0;}
  379.         else
  380.                 {voise=1;beeled=1; }
  381. }

  382. //*************************按下按鍵關閉鬧鐘
  383. void keyclockdown()
  384. {
  385.         if(!START) {flag=0;beeled=1;}
  386. }

  387. //*********************************************

  388. void aoto()                                   //7s后自動關閉鬧鈴
  389. {
  390.         if(flag==1)
  391.         {
  392.                 if(over==10) {flag=0;over=0;}

  393.         }
  394. }

  395. /******************溫度部分**********************/
  396. void dsInit()                //DS18B20復位,初始化函數
  397. {
  398.    
  399.     unsigned int i;  
  400.     ds = 0;
  401.     i = 100;  
  402.      while(i>0) i--;
  403.     ds = 1;   
  404.     i = 4;
  405.      while(i>0) i--;
  406. }

  407. void dsWait()                //
  408. {
  409.       unsigned int i;
  410.       while(ds);  
  411.       while(~ds);
  412.       i = 4;
  413.       while(i > 0) i--;
  414. }


  415. bit readBit()                //讀一位數據函數
  416. {
  417.     unsigned int i;
  418.     bit b;
  419.     ds = 0;
  420.     i++;   
  421.     ds = 1;
  422.    i++; i++;  
  423.     b = ds;
  424.     i = 8;
  425.     while(i>0) i--;
  426.     return b;
  427. }

  428. unsigned char readByte()                //讀一個字節數據函數
  429. {
  430.     unsigned int i;
  431.     unsigned char j, dat;
  432.    dat = 0;
  433.     for(i=0; i<8; i++)
  434.     {
  435.         j = readBit();
  436.       
  437.         dat = (j << 7) | (dat >> 1);                //讀出的數據最低位在最前面,這樣剛好一個字節在dat里
  438.     }
  439.     return dat;
  440. }


  441. void writeByte(unsigned char dat)                //向DS18B20寫一個字節數據函數
  442. {
  443.     unsigned int i;
  444.     unsigned char j;
  445.     bit b;
  446.     for(j = 0; j < 8; j++)
  447.     {
  448.         b = dat & 0x01;
  449.         dat >>= 1;
  450.    
  451.         if(b)                             //寫1
  452.         {
  453.            ds = 0;i++; i++;  
  454.             ds = 1;   
  455.             i = 8; while(i>0) i--;  
  456.         }
  457.         else  
  458.         {
  459.             ds = 0;                  //寫0
  460.           i = 8; while(i>0) i--;  
  461.             ds = 1;
  462.            i++; i++;
  463.         }
  464.    }
  465. }


  466. void sendChangeCmd()                //DS18B20開始獲取溫度并轉換
  467. {
  468.     dsInit();   
  469.     dsWait();   
  470.     delayMs(1);   
  471.     writeByte(0xcc);                //寫跳過讀ROM指令
  472.     writeByte(0x44);                //寫溫度轉換指令
  473. }

  474. void sendReadCmd()                        //讀取寄存器中存儲的溫度數據
  475. {
  476.     dsInit();
  477.     dsWait();
  478.     delayMs(1);
  479.     writeByte(0xcc);
  480.     writeByte(0xbe);
  481. }


  482. int getTmpValue()                                 //得到溫度
  483. {
  484.     unsigned int tmpvalue;
  485.     int value;
  486.     float t;
  487.     unsigned char low, high;
  488.     sendReadCmd();
  489.    
  490.     low = readByte();                //讀低8位
  491.     high = readByte();                //讀高8位
  492.    
  493.     tmpvalue = high;
  494.     tmpvalue <<= 8;                        //兩個字節組合為1個字節
  495.     tmpvalue |= low;

  496.     value = tmpvalue;
  497.     t = value * 0.0625;                 //溫度在寄存器中為12位,分辨率為0.0625度
  498.     value = t * 100 + (value > 0 ? 0.5 : -0.5); //乘以100表示小數點后面只取1位,加0.5是四舍五入,大于0加0.5, 小于0減0.5。
  499.     return value;                        //value是整型
  500. }

  501. //*****************************************************
復制代碼

全部資料51hei下載地址:
ds18b20 lcd1602 聲光報警_仿真電路.zip (21.9 KB, 下載次數: 21)
ds18b20 lcd1602 聲光報警_程序.zip (101.46 KB, 下載次數: 24)
系統框圖.zip (62.43 KB, 下載次數: 9)

評分

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

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 天天操天天摸天天爽 | 成人亚洲片 | 久久精品久久久 | 久久久人成影片一区二区三区 | 精品一区二区三区视频在线观看 | 欧美成人猛片aaaaaaa | 中文字幕第十页 | 成人精品久久日伦片大全免费 | 国产亚洲精品美女久久久久久久久久 | 日韩电影中文字幕 | 日韩久草 | 成人免费黄视频 | 精品乱子伦一区二区三区 | 久久精品小视频 | 亚洲精品一二区 | 国产激情三区 | 成人国产在线视频 | 日韩在线不卡视频 | 一区二区三区在线 | 337p日本欧洲亚洲大胆 | 一区二区三区四区在线视频 | 欧美日韩在线观看视频 | 精品美女 | 国产日韩欧美激情 | 免费的av网站 | 久久亚洲综合 | 欧美中文字幕一区二区 | 日本高清aⅴ毛片免费 | 亚洲精品久久久久久久久久久久久 | 欧美精品一区二区在线观看 | 精品自拍视频 | www.亚洲精品| 黄视频免费在线 | 日韩精品一区二区三区中文字幕 | 久久久久久免费毛片精品 | 色就干 | 一级毛片免费看 | 日韩毛片在线观看 | 国产一区二区三区四区hd | 亚洲天堂影院 | a在线视频 |