找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3936|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)學(xué)習(xí)實踐:讀取DHT11和DHT22測量的溫濕度并在串口打印 附程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:759974 發(fā)表于 2020-11-22 22:29 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
STC15單片機(jī)
實驗名稱:讀取DHT11和DHT22測量的溫度和濕度
實驗內(nèi)容:
        讀取DHT11和DHT22測量的溫度和濕度,使用串口打印
        讀取DS18B20模塊測量溫度作為參考比較
實驗器材:
        STC15W408AS_DIP16 x1
        DS18B20  x1
        DHT11    x1
        DHT22    x1

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


實驗心得:
1、DHT11/22的單總線時序基本相同,可以合并讀取代碼,使用入?yún)⒉煌M(jìn)行小部分區(qū)別處理;
2、DHT11/22的測量結(jié)果可以共用一個結(jié)構(gòu)體類型;
3、DHT11/22的單總線時序很緊湊,MCU發(fā)送啟動信號以后直到讀取40個字節(jié)數(shù)據(jù)之間,代碼盡量緊湊,避免使用printf這種耗時函數(shù),否則容易出現(xiàn)讀取失;

圖1:DHT11和DHT22模塊



圖2:串口打印效果




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

  5.         //設(shè)置STC15W408AS單片機(jī)端口為標(biāo)準(zhǔn)模式
  6.         Config_Port();

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

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

  14.         // 事件處理循環(huán)
  15.         while(1)
  16.         {       
  17.                 UART_Cmd_Check(&uart_cmd_buf, sizeof(uart_cmd_buf)-1);
  18.                
  19.         if (timer_flag_10s)  //每隔10s執(zhí)行以下分支
  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. }
復(fù)制代碼
  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. }
復(fù)制代碼
  1. typedef struct _DHT_Data
  2. {
  3.         uint8 R_H_Byte;        //濕度高位字節(jié)
  4.         uint8 R_L_Byte;        //濕度低位字節(jié)
  5.         uint8 T_H_Byte;        //溫度高位字節(jié)
  6.         uint8 T_L_Byte;        //濕度低位字節(jié)
  7.         uint8 Chk_Sum;        //讀取校驗和
  8.         uint8 Cal_Sum;        //計算校驗和
  9.         float R;                //濕度計算結(jié)果
  10.         float T;                //溫度計算結(jié)果
  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數(shù)據(jù)端口
  18. sbit DHT22_DIO = P1^3; // DHT22數(shù)據(jù)端口

  19. bit DHT_Read(T_DHT_Data *Data, E_DHT_TYPE dht_type);
復(fù)制代碼
  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.         //發(fā)送起始信號
  11.         DHT_Start(dht_type);

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

  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會繼續(xù)拉高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); //讀濕度數(shù)據(jù)高8位
  39.                 Data->R_L_Byte        = DHT_Read_Byte(dht_type); //讀濕度數(shù)據(jù)低8位
  40.                 Data->T_H_Byte        = DHT_Read_Byte(dht_type); //讀溫度數(shù)據(jù)高8位
  41.                 Data->T_L_Byte        = DHT_Read_Byte(dht_type); //讀溫度數(shù)據(jù)低8位
  42.                 Data->Chk_Sum        = DHT_Read_Byte(dht_type); //讀校驗位

  43.                 _Set_IO_Output(dht_type);//DHT DIO數(shù)據(jù)端口設(shè)置為為輸出模式
  44.                 //釋放總線
  45.                 if(E_DHT11 == dht_type)
  46.                         DHT11_DIO = 0;
  47.                 else
  48.                         DHT22_DIO = 0;
  49.                 Delay10us();Delay10us();Delay10us(); //讀取結(jié)束,拉低電平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位累加校驗和,并強(qiáng)制轉(zhuǎn)換為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);//轉(zhuǎn)換濕度數(shù)據(jù)
  61.                                 Data->T = (float)((10 * Data->T_H_Byte + Data->T_L_Byte) / 10);//轉(zhuǎn)換溫度數(shù)據(jù)
  62.                         }
  63.                         else
  64.                         {
  65.                                 Data->R = (float)((256 * Data->R_H_Byte + Data->R_L_Byte) / 10);//轉(zhuǎn)換濕度數(shù)據(jù)
  66.                                 Data->T = (float)((256 * Data->T_H_Byte + Data->T_L_Byte) / 10);//轉(zhuǎn)換溫度數(shù)據(jù)                       
  67.                         }
  68.                         return 0; //返回讀取成功
  69.                 }
  70.         }
  71.         return 1; //返回讀取失敗
  72. }
復(fù)制代碼

完整代碼如下:

圖3:代碼文件組成



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




評分

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

查看全部評分

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

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表