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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機學習實踐:讀取DHT11和DHT22測量的溫濕度并在串口打印 附程序

[復制鏈接]
跳轉到指定樓層
樓主
STC15單片機
實驗名稱:讀取DHT11和DHT22測量的溫度和濕度
實驗內容:
        讀取DHT11和DHT22測量的溫度和濕度,使用串口打印
        讀取DS18B20模塊測量溫度作為參考比較
實驗器材:
        STC15W408AS_DIP16 x1
        DS18B20  x1
        DHT11    x1
        DHT22    x1

在STC15單片機上讀取DHT11和DHT22測量的溫度和濕度的基本方法:
1、MCU發送啟動信號,等待DHT11/22響應
2、DHT11/22響應后,MCU開始讀取40個字節測量數據;
3、檢查校驗和,計算測量結果


實驗心得:
1、DHT11/22的單總線時序基本相同,可以合并讀取代碼,使用入參不同進行小部分區別處理;
2、DHT11/22的測量結果可以共用一個結構體類型;
3、DHT11/22的單總線時序很緊湊,MCU發送啟動信號以后直到讀取40個字節數據之間,代碼盡量緊湊,避免使用printf這種耗時函數,否則容易出現讀取失敗;

圖1:DHT11和DHT22模塊



圖2:串口打印效果




  1. //主函數
  2. void main(void)
  3. {
  4.         uint8 pdata uart_cmd_buf[64] = {0};

  5.         //設置STC15W408AS單片機端口為標準模式
  6.         Config_Port();

  7.         //串口初始化,波特率9600
  8.         UART_Config_1(9600);
  9.        
  10.         //定時器0設置,1ms循環
  11.         Timer0Init();

  12.         //啟動DS18B20
  13.         DS18B20_Start();

  14.         // 事件處理循環
  15.         while(1)
  16.         {       
  17.                 UART_Cmd_Check(&uart_cmd_buf, sizeof(uart_cmd_buf)-1);
  18.                
  19.         if (timer_flag_10s)  //每隔10s執行以下分支
  20.         {
  21.                         printf("\r\n### timer_count %06u seconds ###\r\n", 10*++timer_count);
  22.             timer_flag_10s = 0;

  23.                         DS18B20_Update_Show();
  24.                         DHT_Update_Show();
  25.                 }
  26.                
  27.         }   
  28. }
復制代碼
  1. void DHT_Update_Show(void)
  2. {
  3.         T_DHT_Data dht_data;
  4.         uint8 ret = 0;

  5.         memset(&dht_data, 0x0, sizeof(T_DHT_Data));
  6.         if(0 == DHT_Read(&dht_data, E_DHT11))
  7.         {
  8.                 printf(">>>DHT11  R: %4.1f %%\r\n", dht_data.R);
  9.                 printf(">>>DHT11  T: %4.1f c\r\n", dht_data.T);
  10.         }
  11.         else
  12.         {
  13.                 printf(">>>DHT11_Read failed.\r\n");
  14.         }

  15.         printf("\r\n");

  16.         memset(&dht_data, 0x0, sizeof(T_DHT_Data));
  17.         if(0 == DHT_Read(&dht_data, E_DHT22))
  18.         {
  19.                 printf(">>>DHT22  R: %4.1f %%\r\n", dht_data.R);
  20.                 printf(">>>DHT22  T: %4.1f c\r\n", dht_data.T);
  21.         }
  22.         else
  23.         {
  24.                 printf(">>>DHT22_Read failed.\r\n");
  25.         }

  26.         printf("\r\n");
  27. }
復制代碼
  1. typedef struct _DHT_Data
  2. {
  3.         uint8 R_H_Byte;        //濕度高位字節
  4.         uint8 R_L_Byte;        //濕度低位字節
  5.         uint8 T_H_Byte;        //溫度高位字節
  6.         uint8 T_L_Byte;        //濕度低位字節
  7.         uint8 Chk_Sum;        //讀取校驗和
  8.         uint8 Cal_Sum;        //計算校驗和
  9.         float R;                //濕度計算結果
  10.         float T;                //溫度計算結果
  11. } T_DHT_Data;

  12. typedef enum dht_type
  13. {
  14.         E_DHT11,
  15.         E_DHT22,
  16. } E_DHT_TYPE;

  17. sbit DHT11_DIO = P1^2; // DHT11數據端口
  18. sbit DHT22_DIO = P1^3; // DHT22數據端口

  19. bit DHT_Read(T_DHT_Data *Data, E_DHT_TYPE dht_type);
復制代碼
  1. bit DHT_Read(T_DHT_Data *Data, E_DHT_TYPE dht_type)
  2. {
  3.         uint8 ack = 0;
  4.         uint8 cnt = 0;
  5.         bit   chk = 0;

  6.         if(E_DHT11 == dht_type)
  7.                 if(DEBUG_MODE) printf(">>>DHT11_Read...\r\n");
  8.         else
  9.                 if(DEBUG_MODE) printf(">>>DHT22_Read...\r\n");

  10.         //發送起始信號
  11.         DHT_Start(dht_type);

  12.         _Set_IO_Input(dht_type); //DHT DIO數據端口設置為輸入模式

  13.     //等待低電平
  14.         if(E_DHT11 == dht_type)
  15.                 while(DHT11_DIO);
  16.         else
  17.                 while(DHT22_DIO);

  18.     //DHT11會拉低40~80us
  19.         if(E_DHT11 == dht_type)
  20.                 while(!DHT11_DIO && 10 > cnt++) Delay10us();
  21.         else
  22.                 while(!DHT22_DIO && 10 > cnt++) Delay10us();

  23.         //這里不要使用printf這種耗時長的語句,否則會造成時序錯亂
  24.         //printf(">>>DHT_Read 2-1(cnt=%bu)\r\n", cnt);

  25.         if(10 > cnt)
  26.         {
  27.                 //DHT11會繼續拉高40~80us
  28.                 //Delay100us();

  29.                  cnt = 0;
  30.                  if(E_DHT11 == dht_type)
  31.                          while(DHT11_DIO && 10 > cnt++) Delay10us();
  32.                  else
  33.                          while(DHT22_DIO && 10 > cnt++) Delay10us();
  34.                  
  35.                  if(10 < cnt) return 1; //返回讀取失敗

  36.                 //這里不要使用printf這種耗時長的語句,否則會造成時序錯亂
  37.                 //printf(">>>DHT_Read 2-1(cnt=%bu)\r\n", cnt);

  38.                 Data->R_H_Byte        = DHT_Read_Byte(dht_type); //讀濕度數據高8位
  39.                 Data->R_L_Byte        = DHT_Read_Byte(dht_type); //讀濕度數據低8位
  40.                 Data->T_H_Byte        = DHT_Read_Byte(dht_type); //讀溫度數據高8位
  41.                 Data->T_L_Byte        = DHT_Read_Byte(dht_type); //讀溫度數據低8位
  42.                 Data->Chk_Sum        = DHT_Read_Byte(dht_type); //讀校驗位

  43.                 _Set_IO_Output(dht_type);//DHT DIO數據端口設置為為輸出模式
  44.                 //釋放總線
  45.                 if(E_DHT11 == dht_type)
  46.                         DHT11_DIO = 0;
  47.                 else
  48.                         DHT22_DIO = 0;
  49.                 Delay10us();Delay10us();Delay10us(); //讀取結束,拉低電平30us

  50.                 if(DEBUG_MODE) printf(">>>DHT_Read Data->R_H_Byte: %bu, Data->R_L_Byte: %bu\r\n", Data->R_H_Byte, Data->R_L_Byte);
  51.                 if(DEBUG_MODE) printf(">>>DHT_Read Data->T_H_Byte: %bu, Data->T_L_Byte: %bu\r\n", Data->T_H_Byte, Data->T_L_Byte);
  52.                 if(DEBUG_MODE) printf(">>>DHT_Read Data->Chk_Sum: %bu\r\n", Data->Chk_Sum);

  53.                 //將溫濕度高低8位累加校驗和,并強制轉換為uint8類型
  54.                 Data->Cal_Sum = (uint8)(Data->R_L_Byte + Data->R_H_Byte + Data->T_L_Byte + Data->T_H_Byte);

  55.                 if(DEBUG_MODE) printf(">>>DHT_Read Chk_Sum: %bu, Cal_Sum: %bu\r\n", Data->Chk_Sum, Data->Cal_Sum);

  56.                 if(Data->Chk_Sum == Data->Cal_Sum)//校驗正確
  57.                 {
  58.                         if(E_DHT11 == dht_type)
  59.                         {
  60.                                 Data->R = (float)((10 * Data->R_H_Byte + Data->R_L_Byte) / 10);//轉換濕度數據
  61.                                 Data->T = (float)((10 * Data->T_H_Byte + Data->T_L_Byte) / 10);//轉換溫度數據
  62.                         }
  63.                         else
  64.                         {
  65.                                 Data->R = (float)((256 * Data->R_H_Byte + Data->R_L_Byte) / 10);//轉換濕度數據
  66.                                 Data->T = (float)((256 * Data->T_H_Byte + Data->T_L_Byte) / 10);//轉換溫度數據                       
  67.                         }
  68.                         return 0; //返回讀取成功
  69.                 }
  70.         }
  71.         return 1; //返回讀取失敗
  72. }
復制代碼

完整代碼如下:

圖3:代碼文件組成



UART_DHT_STC15W408AS.7z (17.04 KB, 下載次數: 88)




評分

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

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一级欧美一级在线播放 | 欧美精选一区二区 | 欧美一级片中文字幕 | 日韩视频国产 | 欧美日韩综合精品 | 在线看一区二区 | 99这里只有精品 | 国产欧美日韩精品在线观看 | 国产精品一区二区在线 | 欧美视频免费 | a中文在线视频 | xxxcom在线观看 | 亚洲欧美视频一区 | 欧美久久久久久久久 | 日韩天堂av| 日韩欧美在线观看视频网站 | 日韩精品视频在线 | 国产成人小视频 | 国产精品国产三级国产aⅴ无密码 | 国产高清精品一区 | 久久久高清 | 国产精品久久久久久婷婷天堂 | 这里精品 | 三级av在线 | 久在草 | 日韩国产高清在线观看 | 四虎影视 | 午夜精品一区二区三区在线视频 | 天天天堂 | 国产一级视频在线 | 国产精品色 | 欧美亚洲视频在线观看 | 日本免费一区二区三区四区 | 亚洲+变态+欧美+另类+精品 | 91视频精选| 成人精品在线观看 | 欧美在线观看一区二区 | 91精品国产91久久久久游泳池 | 国产精品日产欧美久久久久 | 九九久久久 | 国产精品久久久久一区二区三区 |