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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4173|回復: 3
收起左側

dht11和ds18b20溫濕度控制 單片機程序

[復制鏈接]
ID:499469 發表于 2019-6-5 12:44 | 顯示全部樓層 |閱讀模式
基于51單片機,傳感器使用dht11和ds18b20,dht11測溫度精度有限,18b20可以彌補。第一行顯示dht11采集到的濕度和溫度,以及繼電器狀態。第二行顯示18b20采集到溫度和THI。THi是畜牧業衡量動物熱應激指數的標準,不需要的刪除掉。繼電器是通過THI指數高低控制的。
1.jpg

單片機源程序如下:
  1. /*********************************************************************************************
  2. 程序名:    DHT11-1602
  3. 編寫人:    fby
  4. 編寫時間:  2019年3月21日
  5. 硬件支持:  STC89C52RC  DHT11  LCD1602
  6. 接口說明:  DHT11:VCC DATA NC GND
  7. *********************************************************************************************
  8. 說明:1、單片機是STC89C52RC,晶振頻率11.0592MHz,實驗成功。
  9.           2、好東西要共享,大家隨意折騰~~
  10. *********************************************************************************************/
  11. #include "reg52.h"
  12. #include<intrins.h>  //此文件中定義了單片機的一些特殊功能寄存器
  13. #include<stdio.h>
  14. #include"temp.h"       

  15.                          


  16. #define uchar unsigned char        //無符號字符型類型數據
  17. #define uint unsigned int //無符號整型數據
  18.         #define ulong unsigned long //無符號整型數據
  19.         #define xiao float //xiaoshu
  20. #define IODATA  P0
  21.        

  22. uchar dat_r[10];          //用于存放從DHT11讀取到的數值
  23.           uchar sData[10];

  24. sbit DATA=P2^0;   //定義數據線
  25. sbit RS=P2^6; //定義rs端口
  26. sbit RW=P2^5; //定義rw端口
  27. sbit E=P2^7;
  28.           sbit jidian=P3^7;  //定義繼電器
  29.        
  30.         static uint i;
  31.         extern uint zheng;

  32.        
  33.        
  34.        


  35.              
  36. void delay200ms(void)   //誤差 0us
  37. {
  38.     unsigned char a,b,c;
  39.     for(c=4;c>0;c--)
  40.         for(b=116;b>0;b--)
  41.             for(a=214;a>0;a--);
  42.     _nop_();  //if Keil,require use intrins.h
  43. }

  44.         /*******************************************************************************
  45. * 函 數 名         : datapros()
  46. * 函數功能                   : 溫度讀取處理轉換函數
  47. * 輸    入         : temp
  48. * 輸    出         : 無
  49. *******************************************************************************/

  50. void datapros(int temp)          
  51. {
  52.            float tp;  
  53.         if(temp< 0)                                //當溫度值為負數
  54.           {
  55.       sData[0]=0;
  56.                 //因為讀取的溫度是實際溫度的補碼,所以減1,再取反求出原碼
  57.                 temp=temp-1;
  58.                 temp=~temp;
  59.                 tp=temp;
  60.                 temp=tp*0.0625*100+0.5;       
  61.                 //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
  62.                 //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
  63.                 //算加上0.5,還是在小數點后面。

  64.           }
  65.         else
  66.           {                       
  67.                 sData[0]=1;
  68.                 tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量
  69.                 //如果溫度是正的那么,那么正數的原碼就是補碼它本身
  70.                 temp=tp*0.0625*100+0.5;       
  71.                 //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
  72.                 //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
  73.                 //算加上0.5,還是在小數點后面。
  74.         }
  75.         //顯示數據處理
  76.         sData[1] = '0'+(temp / 10000);
  77.         sData[2] = '0'+(temp % 10000 / 1000);
  78.         sData[3] = '0'+(temp % 1000 / 100) ;
  79.         sData[4] = '0'+(temp % 100 / 10);
  80.         sData[5] = '0'+(temp % 10);
  81.           //真實數據
  82.         sData[7] = temp / 10000;
  83.         sData[8] = temp % 10000 / 1000;
  84.         sData[9] = temp % 1000 / 100 ;
  85.         sData[10] =temp % 100 / 10;
  86. }

  87.         /*******************************************************************************
  88. * 函 數 名         : Timer1Init
  89. * 函數功能                   : 定時器1初始化
  90. * 輸    入         : 無
  91. * 輸    出         : 無
  92. *******************************************************************************/
  93.         void Timer1Init()
  94. {
  95.         TMOD|=0X10;//選擇為定時器1模式,工作方式1,僅用TR1打開啟動。

  96.         TH1=0XFC;        //給定時器賦初值,定時1ms
  97.         TL1=0X18;       
  98.         ET1=1;//打開定時器1中斷允許
  99.         EA=1;//打開總中斷
  100.         TR1=1;//打開定時器                       
  101. }



  102. /*********************************************************************************************
  103. 函數名:延時函數
  104. 調  用:Delay30us();/Delay20ms();/Delay1s();
  105. 參  數:無
  106. 返回值:無
  107. 結  果:延時相應時間
  108. 備  注:振蕩晶體為11.0592MHz(所有延時函數Copy自STC-ISP(v6.85).exe)
  109. **********************************************************************************************/
  110. void Delay30us()                //@11.0592MHz-40
  111. {
  112.         unsigned char i;

  113.         i = 11;
  114.         while (--i);
  115. }


  116. void Delay20ms()                //@11.0592MHz
  117. {
  118.         unsigned char i, j;

  119.         i = 36;
  120.         j = 217;
  121.         do
  122.         {
  123.                 while (--j);
  124.         } while (--i);
  125. }


  126. void Delay1s()                //@11.0592MHz
  127. {
  128.         unsigned char i, j, k;

  129.         _nop_();
  130.         i = 8;
  131.         j = 1;
  132.         k = 243;
  133.         do
  134.         {
  135.                 do
  136.                 {
  137.                         while (--k);
  138.                 } while (--j);
  139.         } while (--i);
  140. }


  141. /*********************************************************************************************
  142. 函數名:DHT11啟動函數
  143. 調  用:無
  144. 參  數:無
  145. 返回值:無
  146. 結  果:DHT11開始工作
  147. 備  注:
  148. **********************************************************************************************/
  149. void DHT11_start()                 // 主機控制DHT11開始工作
  150. {
  151.    DATA=1;                                 // 主線空閑狀態
  152.    _nop_();
  153.    _nop_();
  154.    DATA=0;                                 // 主機發送開始工作信號
  155.    Delay20ms();   //延時18ms以上
  156.    DATA=1;                                 // 拉高并延時等待DHT11響應
  157.    Delay30us();
  158. }
  159. /*********************************************************************************************
  160. 函數名:DHT11讀數據函數
  161. 調  用:? = DHT11_rec_byte();
  162. 參  數:無
  163. 返回值:
  164. 結  果:讀DHT11數據并保存到dat
  165. 備  注:
  166. **********************************************************************************************/

  167. uchar DHT11_rec_byte()      //接收一個字節
  168. {
  169.    uchar i,dat=0;
  170.   for(i=0;i<8;i++)    //從高到低依次接收8位數據
  171.    {         
  172.       while(!DATA);   ////等待50us低電平過去
  173.       Delay30us();
  174.           Delay30us();     //延時60us,如果還為高則數據為1,否則為0
  175.       dat<<=1;           //左移位使正確接收8位數據,數據為0時直接移位
  176.       if(DATA==1)    //數據為1時,使dat加1來接收數據1
  177.          dat+=1;
  178.       while(DATA);  //等待數據線拉低   
  179.     }  
  180.     return dat;
  181. }

  182. /*********************************************************************************************
  183. 函數名:接收DHT11的40位的數據并校驗
  184. 調  用:? = DHT11_receive();
  185. 參  數:無
  186. 返回值:無
  187. 結  果:結果保存到dat_r[i]中
  188. 備  注:
  189. **********************************************************************************************/
  190. void DHT11_receive()      //接收40位的數據
  191. {
  192.     uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;

  193.         //xiao thi;
  194. //uint zheng;
  195.     DHT11_start();                 // 主機控制DHT11開始工作
  196.     if(DATA==0)
  197.     {
  198.         while(DATA==0);   //等待拉高     
  199.         Delay30us();
  200.                 Delay30us();
  201.                 Delay30us();  //拉高后延時80us
  202.         R_H=DHT11_rec_byte();    //接收濕度高八位  
  203.         R_L=DHT11_rec_byte();    //接收濕度低八位  
  204.         T_H=DHT11_rec_byte();    //接收溫度高八位  
  205.         T_L=DHT11_rec_byte();    //接收溫度低八位
  206.         revise=DHT11_rec_byte(); //接收校正位

  207.         Delay30us();    //結束

  208.         if((R_H+R_L+T_H+T_L)==revise)      //校正
  209.         {
  210.             RH=R_H;
  211.             RL=R_L;
  212.             TH=T_H;
  213.             TL=T_L;

  214.                                
  215.         }
  216.         /*數據處理,方便顯示*/
  217.         dat_r[0]='0'+(RH/10);
  218.         dat_r[1]='0'+(RH%10);
  219.         dat_r[2]='0'+(TH/10);
  220.         dat_r[3]='0'+(TH%10);
  221.                                
  222.                                 dat_r[4]=RH;
  223.       
  224.         
  225.                                 //dat_r[4]='0'+(zheng/100);
  226.                           //dat_r[5]='0'+(zheng%100/10);
  227.                                 //dat_r[6]='0'+(zheng%10);
  228.                                 //dat_r[7]='0'+(zheng/10);
  229.                                 //dat_r[8]=Thi;
  230.                                 //dat_r[7]='0'+(h);
  231.                                 //dat_r[7]='0'+(zheng);


  232.        
  233.     }
  234. }

  235. /********************************************************************
  236. * 名稱 : bit Busy(void)
  237. * 功能 : 這個是一個讀狀態函數,讀出函數是否處在忙狀態
  238. * 輸入 : 輸入的命令值
  239. * 輸出 : 無
  240. ***********************************************************************/
  241. void Busy(void)
  242. {
  243. bit busy_flag = 1;
  244. IODATA  = 0xff;
  245. RS = 0;          //指令關
  246. Delay30us();
  247. RW = 1;          //讀狀態
  248. Delay30us();
  249. E = 1;        //使能高電平
  250. while(1)
  251. {
  252. busy_flag = (bit)(IODATA  & 0x80); //強制取最高位
  253. if(busy_flag == 0)
  254. {
  255. break;
  256. }
  257. }
  258. E = 0;           //E 1->0,rs=0,rw=1,
  259.            //將數據寄存器內的數據讀到DB0~DB7,分別將狀態標志BF和地址計數器(AC)內容讀到DB7和DB6~DB0。

  260. }

  261. /********************************************************************
  262. * 名稱 : lcd1602_write_cmd(uchar del)
  263. * 功能 : 1602命令函數
  264. * 輸入 : 輸入的命令值
  265. * 輸出 : 無
  266. ***********************************************************************/
  267. void lcd1602_write_cmd(uchar del)
  268. {
  269. RS = 0;
  270. Delay30us();
  271. RW = 0;
  272. Delay30us();
  273. E = 0;
  274. Delay30us();
  275. IODATA  = del;
  276. Delay30us();
  277. E = 1;
  278. Delay30us();
  279. E = 0;                        //E 1->0,rs=0,rw=0, 將指令代碼寫入指令寄存器中
  280. }

  281. /********************************************************************
  282. * 名稱 : lcd1602_write_data(uchar del)
  283. * 功能 : 1602寫數據函數
  284. * 輸入 : 需要寫入1602的數據
  285. * 輸出 : 無
  286. ***********************************************************************/

  287. void lcd1602_write_data(uchar del)
  288. {
  289. Busy();      
  290. Delay30us();
  291. RS = 1;
  292. Delay30us();
  293. RW = 0;
  294. Delay30us();
  295. E = 0;
  296. Delay30us();
  297. IODATA  = del;
  298. Delay30us();
  299. E = 1;
  300. Delay30us();
  301. E = 0;                          //E 1->0,rs=1,rw=0, 數據寫入數據寄存器中
  302. }

  303. /********************************************************************
  304. * 名稱 : lcd1602_init()
  305. * 功能 : 1602初始化,請參考1602的資料
  306. * 輸入 : 無
  307. * 輸出 : 無
  308. ***********************************************************************/
  309. void lcd1602_init(void)
  310. {
  311. Delay20ms();
  312. lcd1602_write_cmd(0x38);         //8位數據,雙列,5*7字形
  313. Delay20ms();
  314. lcd1602_write_cmd(0x38);
  315. Delay20ms();
  316. lcd1602_write_cmd(0x38);
  317. Busy();
  318. lcd1602_write_cmd(0x08);// 只開顯示
  319. Busy();   
  320. lcd1602_write_cmd(0x01);        //清屏
  321. Busy();
  322. lcd1602_write_cmd(0x06);//顯示地址遞增,即寫一個數據后,顯示位置右移一位
  323. Busy();
  324. lcd1602_write_cmd(0x0c);        //開啟顯示屏,關光標,光標不閃爍
  325. }

  326. /********************************************************************
  327. * 名稱 : lcd1602_char(uchar hang,uchar lie,char sign)
  328. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調用該函數如下
  329. L1602_char(1,5,'b')
  330. * 輸入 : 行,列,需要輸入1602的數據
  331. * 輸出 : 無
  332. ***********************************************************************/
  333. void lcd1602_char(uchar hang,uchar lie,char sign)
  334. {
  335. uchar a;
  336. if(hang == 1)
  337. {
  338. a = 0x80;
  339. }
  340. if(hang == 2)
  341. {
  342. a = 0xc0;
  343. }
  344. a = a + lie - 1;
  345. Busy();
  346. lcd1602_write_cmd(a);  //置數據存貯器地址
  347. Busy();
  348. lcd1602_write_data(sign);
  349. }




  350. /********************************************************************
  351. * 名稱 : lcd1602_string(uchar hang,uchar lie,uchar *p)
  352. * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
  353. L1602_string(1,5,"ab cd ef;")
  354. * 輸入 : 行,列,需要輸入1602的數據
  355. * 輸出 : 無
  356. ***********************************************************************/

  357. void lcd1602_string(uchar hang,uchar lie,uchar *p)
  358. {
  359. uchar a;
  360. if(hang == 1)
  361. {
  362. a = 0x80;
  363. }
  364. if(hang == 2)
  365. {
  366. a = 0xc0;
  367. }
  368. a = a + lie - 1;
  369. while(1)
  370. {
  371. Busy();
  372. lcd1602_write_cmd(a);
  373. Busy();
  374. lcd1602_write_data(*p);
  375. a++;
  376. p++;   
  377. if((*p == '\0')||(a==0x90)||(a==0xd0)) //字符結束或每行最后一個字符
  378. {
  379. break;
  380. }
  381. }
  382. }

  383. void kongzhi()    //控制函數
  384.    {
  385.    if(dat_r[8]>78) {jidian=0;lcd1602_string(1,16,"K");}     // 上限74
  386.       else if(dat_r[8]<77) {jidian=1;lcd1602_string(1,16,"G");}    // 下限72
  387.        else {lcd1602_string(1,16,"L");}  
  388.       }


  389.             //thi計算函數
  390.            void thisuan()
  391.            {
  392.            xiao th;
  393.            uint thi,shi,wen;
  394.              shi=dat_r[4]        ;
  395.                  wen=sData[7]*100+sData[8]*10+sData[9]+sData[10]/10 ;
  396.                     th=wen*0.81+(0.99*wen-14.3)*shi/100+46.3+0.5;
  397.                          thi=th*10;
  398.                           dat_r[5]='0'+(thi/100);
  399.                           dat_r[6]='0'+(thi%100/10);
  400.                                 dat_r[7]='0'+(thi%10);
  401.                         dat_r[8]=th;
  402.            }   

  403. /*********************************************************************************************
  404. 函數名:主函數
  405. 調  用:無
  406. 參  數:無
  407. 返回值:無
  408. 結  果:讀DHT11數據并送到1602顯示
  409. 備  注:
  410. **********************************************************************************************/
  411. void main (void)
  412. {

  413.        
  414.        Delay20ms();
  415.         lcd1602_init();         //LCD初始化

  416.         while(1)
  417.         {
  418.                                         datapros(Ds18b20ReadTemp());
  419.                 delay200ms;              //經測試,兩次連讀要至少延時80ms        
  420.                 DHT11_receive();//接受數據
  421.                                                 thisuan();
  422.                                        
  423.                                        
  424.                                
  425.       
  426.                 lcd1602_string(1,1,"S:");
  427.                                               lcd1602_char(1,3,dat_r[0]);
  428.                 lcd1602_char(1,4,dat_r[1]);
  429.                                               lcd1602_string(1,5,"%");
  430.                                        
  431.                 lcd1602_string(1,7,"W:");
  432.                 lcd1602_char(1,8,dat_r[2]);
  433.                 lcd1602_char(1,9,dat_r[3]);
  434.                 lcd1602_char(1,10,0XDF);
  435.                 lcd1602_string(1,11,"C");
  436.                                        
  437.                                         lcd1602_string(2,1,"T:");
  438.                                         lcd1602_char(2,3,dat_r[5]);
  439.                                         lcd1602_char(2,4,dat_r[6]);
  440.                                         lcd1602_string(2,5,".");
  441.                                         lcd1602_char(2,6,dat_r[7]);
  442.                                        
  443.                                        
  444.                                         if(sData[0]==0)
  445.                                         {
  446.                                         lcd1602_string(2,8,"-");
  447.                                         }
  448.                                        
  449.                                                 if(sData[7]>0)
  450.                                                 {
  451.                                                         lcd1602_char(2,9,sData[1]);
  452.                                                 }
  453.                                        
  454.                                                 lcd1602_char(2,10,sData[2]);
  455.                                                         lcd1602_char(2,11,sData[3]);
  456.                                         lcd1602_string(2,12,".");
  457.                                                                 lcd1602_char(2,13,sData[4]);
  458.                                                                 //lcd1602_char(2,14,sData[5]);
  459.                                        
  460.                                        
  461.                                         lcd1602_string(1,13,"ji:");

  462.                                
  463.                                         kongzhi();
  464.                                
  465.                
  466.                                

  467. }}  

  468.                                
  469.                                
  470. //void Timer0() interrupt 3  //定時器中斷
  471. //{
  472.        
  473.        
  474.         //TH0=0XFC;        //給定時器賦初值,定時1ms
  475.         //TL0=0X18;
  476. //i++;
  477.        
  478. //}
復制代碼

所有資料51hei提供下載:
THI dht11 18b20.zip (78.98 KB, 下載次數: 90)

評分

參與人數 2黑幣 +55 收起 理由
Eli_ + 5 贊一個!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品久久久久久久久久久久久 | 免费一级黄色 | 日韩av第一页 | 国产精品成人在线 | 日韩欧美国产精品一区二区三区 | 五月天激情综合网 | 国产成视频在线观看 | 午夜精品一区二区三区在线 | 精品亚洲永久免费精品 | 在线国产一区 | 国产精品美女久久久 | 久久久久久成人 | 国产高清视频在线观看 | 在线看av网址 | 久草中文在线观看 | 欧美一区视频 | 日韩精品视频一区二区三区 | 日日拍夜夜 | 国产区视频在线观看 | www.久久久.com | 久久福利电影 | 一区二区视频 | 成人在线观看免费爱爱 | 91国内精精品久久久久久婷婷 | 日韩精品视频在线播放 | 亚洲综合大片69999 | 99精品视频网 | 欧洲一区二区三区 | 久久久久亚洲 | 日本精品一区 | 久久久久久久久综合 | 亚洲网站在线观看 | 亚洲精品高清视频 | 亚洲精品久久区二区三区蜜桃臀 | 亚洲人成人一区二区在线观看 | 成人啊啊啊 | 国产精品久久久久久久久久三级 | 精品国产一二三区 | 欧美日韩综合视频 | 久久久久亚洲精品中文字幕 | 国际精品鲁一鲁一区二区小说 |