主題 | 內容 | 教學目的/擴展視頻 |
---|---|---|
DHT11芯片 | 電路連接,手冊分析。驅動程序,讀出數據。 | 能讀出溫濕度值即可。 |
師從洋桃電子,杜洋老師
📑文章目錄
- 一、硬件接口與通信原理
- 1.1 硬件連接拓撲
- 1.2 單總線通信時序
- 二、驅動代碼深度解析(dht11.c)
- 2.1 GPIO模式切換
- 2.2 起始信號生成
- 2.3 單bit數據讀取
- 2.4 單字節數據讀取
- 2.5 完整數據讀取流程
- 三、關鍵優化策略
- 3.1 時序精度提升
- 3.2 錯誤重試機制
- 3.3 數據濾波處理
- 四、典型應用場景
- 五、開發注意事項
- 六、相關資源
▲ 回顧上期🔍DHT11數字溫濕度傳感器驅動開發全解析(上) | 零基礎入門STM32第八十六步
▲ 回顧上期🔍DHT11數字溫濕度傳感器驅動開發全解析(中) | 零基礎入門STM32第八十七步
一、硬件接口與通信原理
1.1 硬件連接拓撲
引腳 | 連接目標 | 說明 |
---|---|---|
VDD | 3.3V電源 | 供電范圍3-5.5V DC |
DATA | PA15 | 單總線雙向通信引腳 |
GND | 系統GND | 電源參考地 |
1.2 單總線通信時序
二、驅動代碼深度解析(dht11.c)
2.1 GPIO模式切換
// 設置為推挽輸出模式
void DHT11_IO_OUT(void) {GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = DHT11_IO;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽輸出GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 高速模式GPIO_Init(DHT11PORT, &GPIO_InitStruct);
}// 設置為上拉輸入模式
void DHT11_IO_IN(void) {GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = DHT11_IO;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 上拉輸入GPIO_Init(DHT11PORT, &GPIO_InitStruct);
}
設計要點:
- 輸出模式用于主機控制總線電平
- 輸入模式配合上拉電阻保證總線穩定
- 50MHz速度滿足單總線時序要求
2.2 起始信號生成
void DHT11_RST(void) {DHT11_IO_OUT(); // 切換輸出模式GPIO_ResetBits(DHT11PORT, DHT11_IO); // 拉低總線delay_ms(20); // 保持低電平20ms(手冊要求≥18ms)GPIO_SetBits(DHT11PORT, DHT11_IO); // 釋放總線delay_us(30); // 等待20-40us
}
時序控制:
- 20ms低電平:確保滿足最小18ms要求
- 30us高電平:預留足夠響應時間
2.3 單bit數據讀取
u8 Dht11_ReadBit(void) {u8 retry = 0;// 等待50us低電平起始信號while(GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO) && retry<100) {retry++;delay_us(1);}retry = 0;// 等待高電平到來while(!GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO) && retry<100) {retry++;delay_us(1);}delay_us(40); // 關鍵采樣點return GPIO_ReadInputDataBit(DHT11PORT,DHT11_IO) ? 1 : 0;
}
解碼原理:
- 26-28μs高電平:數據0
- 70μs高電平:數據1
- 40μs延遲采樣:準確區分高低電平
2.4 單字節數據讀取
u8 Dht11_ReadByte(void) {u8 i, dat = 0;for(i=0; i<8; i++) {dat <<= 1; // 高位先出dat |= Dht11_ReadBit();}return dat;
}
位操作邏輯:
- 左移操作保留高位
- 按位或操作累積數據位
- 循環8次組成完整字節
2.5 完整數據讀取流程
u8 DHT11_ReadData(u8 *h) {u8 buf[5];DHT11_RST(); // 發送起始信號if(Dht11_Check() == 0) { // 檢測傳感器響應for(int i=0; i<5; i++) { // 讀取5字節數據buf[i] = Dht11_ReadByte();}// 校驗和驗證if((buf[0]+buf[1]+buf[2]+buf[3]) == buf[4]) {h[0] = buf[0]; // 濕度整數部分h[1] = buf[2]; // 溫度整數部分return 0; // 成功標志}}return 1; // 失敗標志
}
數據格式解析:
字節 | 數據內容 | 數值范圍 |
---|---|---|
0 | 濕度整數 | 20-90%RH |
1 | 濕度小數 | 固定為0 |
2 | 溫度整數 | 0-50℃ |
3 | 溫度小數 | 固定為0 |
4 | 校驗和 | 前四字節和 |
三、關鍵優化策略
3.1 時序精度提升
// 使用硬件定時器替代delay_us
void Delay_us(uint16_t us) {TIM2->CNT = 0;while(TIM2->CNT < us);
}
3.2 錯誤重試機制
u8 DHT11_ReadData(u8 *h) {u8 retry = 3;while(retry--) {// ...讀取邏輯...if(校驗成功) return 0;delay_ms(100); // 重試間隔}return 1;
}
3.3 數據濾波處理
#define FILTER_SIZE 5
u8 filter_buf[FILTER_SIZE][2];void DHT11_Filter(u8 *h) {static u8 index = 0;// 存儲當前值filter_buf[index][0] = h[0];filter_buf[index][1] = h[1];index = (index+1) % FILTER_SIZE;// 排序取中值// ...實現排序算法...
}
四、典型應用場景
五、開發注意事項
- 電源穩定性:建議并聯100nF陶瓷電容
- 信號線長度:超過20米需增加屏蔽措施
- 采樣間隔:嚴格≥1秒(手冊要求)
- 環境適應:
- 避免冷凝環境
- 遠離發熱元件
- 防止化學污染
六、相關資源
[1] 洋桃電子B站課程-STM32入門100步
[2] STM32官方文檔手冊
[3] STM32F103固件函數庫用戶手冊(中文)
[4] DHT11說明書(中文)
[5] DHT11溫濕度顯示程序
💬 技術討論(請在評論區留言~)
📌 下期預告:下一期將探討加速度傳感器,歡迎持續關注!
點擊查閱🔍往期【STM32專欄】文章
版權聲明:本文采用[CC BY-NC-SA 4.0]協議,轉載請注明來源
實測開發版:洋桃1號開發版(基于STM32F103C8T6)
更新日志:
- v1.0 初始版本(2025-03-30)