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模塊
51hei圖片_20201122222212.jpg (64.75 KB, 下載次數: 70)
下載附件
2020-11-22 22:22 上傳
圖2:串口打印效果
Screenshot 2020-11-22 215742.png (67.05 KB, 下載次數: 54)
下載附件
2020-11-22 22:22 上傳
- //主函數
- void main(void)
- {
- uint8 pdata uart_cmd_buf[64] = {0};
- //設置STC15W408AS單片機端口為標準模式
- Config_Port();
- //串口初始化,波特率9600
- UART_Config_1(9600);
-
- //定時器0設置,1ms循環
- Timer0Init();
- //啟動DS18B20
- DS18B20_Start();
- // 事件處理循環
- while(1)
- {
- UART_Cmd_Check(&uart_cmd_buf, sizeof(uart_cmd_buf)-1);
-
- if (timer_flag_10s) //每隔10s執行以下分支
- {
- printf("\r\n### timer_count %06u seconds ###\r\n", 10*++timer_count);
- timer_flag_10s = 0;
- DS18B20_Update_Show();
- DHT_Update_Show();
- }
-
- }
- }
復制代碼- void DHT_Update_Show(void)
- {
- T_DHT_Data dht_data;
- uint8 ret = 0;
- memset(&dht_data, 0x0, sizeof(T_DHT_Data));
- if(0 == DHT_Read(&dht_data, E_DHT11))
- {
- printf(">>>DHT11 R: %4.1f %%\r\n", dht_data.R);
- printf(">>>DHT11 T: %4.1f c\r\n", dht_data.T);
- }
- else
- {
- printf(">>>DHT11_Read failed.\r\n");
- }
- printf("\r\n");
- memset(&dht_data, 0x0, sizeof(T_DHT_Data));
- if(0 == DHT_Read(&dht_data, E_DHT22))
- {
- printf(">>>DHT22 R: %4.1f %%\r\n", dht_data.R);
- printf(">>>DHT22 T: %4.1f c\r\n", dht_data.T);
- }
- else
- {
- printf(">>>DHT22_Read failed.\r\n");
- }
- printf("\r\n");
- }
復制代碼- typedef struct _DHT_Data
- {
- uint8 R_H_Byte; //濕度高位字節
- uint8 R_L_Byte; //濕度低位字節
- uint8 T_H_Byte; //溫度高位字節
- uint8 T_L_Byte; //濕度低位字節
- uint8 Chk_Sum; //讀取校驗和
- uint8 Cal_Sum; //計算校驗和
- float R; //濕度計算結果
- float T; //溫度計算結果
- } T_DHT_Data;
- typedef enum dht_type
- {
- E_DHT11,
- E_DHT22,
- } E_DHT_TYPE;
- sbit DHT11_DIO = P1^2; // DHT11數據端口
- sbit DHT22_DIO = P1^3; // DHT22數據端口
- bit DHT_Read(T_DHT_Data *Data, E_DHT_TYPE dht_type);
復制代碼- bit DHT_Read(T_DHT_Data *Data, E_DHT_TYPE dht_type)
- {
- uint8 ack = 0;
- uint8 cnt = 0;
- bit chk = 0;
- if(E_DHT11 == dht_type)
- if(DEBUG_MODE) printf(">>>DHT11_Read...\r\n");
- else
- if(DEBUG_MODE) printf(">>>DHT22_Read...\r\n");
- //發送起始信號
- DHT_Start(dht_type);
- _Set_IO_Input(dht_type); //DHT DIO數據端口設置為輸入模式
- //等待低電平
- if(E_DHT11 == dht_type)
- while(DHT11_DIO);
- else
- while(DHT22_DIO);
- //DHT11會拉低40~80us
- if(E_DHT11 == dht_type)
- while(!DHT11_DIO && 10 > cnt++) Delay10us();
- else
- while(!DHT22_DIO && 10 > cnt++) Delay10us();
- //這里不要使用printf這種耗時長的語句,否則會造成時序錯亂
- //printf(">>>DHT_Read 2-1(cnt=%bu)\r\n", cnt);
- if(10 > cnt)
- {
- //DHT11會繼續拉高40~80us
- //Delay100us();
- cnt = 0;
- if(E_DHT11 == dht_type)
- while(DHT11_DIO && 10 > cnt++) Delay10us();
- else
- while(DHT22_DIO && 10 > cnt++) Delay10us();
-
- if(10 < cnt) return 1; //返回讀取失敗
- //這里不要使用printf這種耗時長的語句,否則會造成時序錯亂
- //printf(">>>DHT_Read 2-1(cnt=%bu)\r\n", cnt);
- Data->R_H_Byte = DHT_Read_Byte(dht_type); //讀濕度數據高8位
- Data->R_L_Byte = DHT_Read_Byte(dht_type); //讀濕度數據低8位
- Data->T_H_Byte = DHT_Read_Byte(dht_type); //讀溫度數據高8位
- Data->T_L_Byte = DHT_Read_Byte(dht_type); //讀溫度數據低8位
- Data->Chk_Sum = DHT_Read_Byte(dht_type); //讀校驗位
- _Set_IO_Output(dht_type);//DHT DIO數據端口設置為為輸出模式
- //釋放總線
- if(E_DHT11 == dht_type)
- DHT11_DIO = 0;
- else
- DHT22_DIO = 0;
- Delay10us();Delay10us();Delay10us(); //讀取結束,拉低電平30us
- 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);
- 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);
- if(DEBUG_MODE) printf(">>>DHT_Read Data->Chk_Sum: %bu\r\n", Data->Chk_Sum);
- //將溫濕度高低8位累加校驗和,并強制轉換為uint8類型
- Data->Cal_Sum = (uint8)(Data->R_L_Byte + Data->R_H_Byte + Data->T_L_Byte + Data->T_H_Byte);
- if(DEBUG_MODE) printf(">>>DHT_Read Chk_Sum: %bu, Cal_Sum: %bu\r\n", Data->Chk_Sum, Data->Cal_Sum);
- if(Data->Chk_Sum == Data->Cal_Sum)//校驗正確
- {
- if(E_DHT11 == dht_type)
- {
- Data->R = (float)((10 * Data->R_H_Byte + Data->R_L_Byte) / 10);//轉換濕度數據
- Data->T = (float)((10 * Data->T_H_Byte + Data->T_L_Byte) / 10);//轉換溫度數據
- }
- else
- {
- Data->R = (float)((256 * Data->R_H_Byte + Data->R_L_Byte) / 10);//轉換濕度數據
- Data->T = (float)((256 * Data->T_H_Byte + Data->T_L_Byte) / 10);//轉換溫度數據
- }
- return 0; //返回讀取成功
- }
- }
- return 1; //返回讀取失敗
- }
復制代碼
完整代碼如下:
圖3:代碼文件組成
Screenshot 2020-11-22 221942.png (13.19 KB, 下載次數: 47)
下載附件
2020-11-22 22:23 上傳
UART_DHT_STC15W408AS.7z
(17.04 KB, 下載次數: 88)
2020-11-22 22:28 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|