STM32 HAL DHT11驅動程序

DHT11驅動程序會占用TIM3定時器,進行高精度延時。程序共包含4個文件?

DHT11.c?DHT11.h delay.c?delay.h

DHT11.c

#include "stm32f1xx_hal.h"
#include "dht11.h"
#include "delay.h"  // 添加延時頭文件
#define DHT_PORT  GPIOB
#define DHT_PIN  GPIO_PIN_10
//配置A9為輸出模式
void DHT11_Output_Mode(void)
{GPIO_InitTypeDef GPIO_InitStructure;__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStructure.Pin   = DHT_PIN; 	GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;	//推挽輸出GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStructure.Pull  = GPIO_NOPULL;HAL_GPIO_Init(DHT_PORT, &GPIO_InitStructure);
}
//配置A9為輸入模式
void DHT11_Input_Mode(void)
{GPIO_InitTypeDef GPIO_InitStructure;__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStructure.Pin   = DHT_PIN; 	//9號引腳GPIO_InitStructure.Mode  = GPIO_MODE_INPUT;  //浮空輸入GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStructure.Pull  = GPIO_NOPULL;HAL_GPIO_Init(DHT_PORT, &GPIO_InitStructure);
}//A9輸出電平0/1
void DHT11_DQ_OUT(uint8_t BitValue)
{HAL_GPIO_WritePin(DHT_PORT, DHT_PIN, (GPIO_PinState)BitValue);
}//A9讀取輸入電平0/1
uint8_t DHT11_DQ_IN(void)
{return HAL_GPIO_ReadPin(DHT_PORT, DHT_PIN);
}//DHT11復位信號
void DHT11_Reset(void)
{DHT11_Output_Mode();DHT11_DQ_OUT(0);//拉低DQ,復位信號的開始delay_ms(20);//拉低至少18msDHT11_DQ_OUT(1);// 將DHT11的DQ引腳拉高,結束復位信號delay_us(25); //在拉高DQ之后,DHT11會開始其內部復位過程,拉高20-40us
}//檢測是否有DHT11存在,0存在,1不存在
uint8_t DHT11_Check(void)
{uint8_t retry = 0;//初始為0,用來重復計次DHT11_Input_Mode();//設置PA9為輸入模式,接收DHT11信號// 等待DHT11拉低DQ引腳,這通常發生在復位信號之后的40-80微秒內while(DHT11_DQ_IN() && retry < 100)//DHT拉低40-80us{retry++;//每次循環計次加一delay_us(1);}//如果在計次100次內沒有被拉低,返回1則認為DHT11沒有響應,否則重置計次變量為0,//為下一次等待階段做準備if(retry >= 100) return 1; else {retry = 0;}// 等待DHT11拉高DQ引腳,在拉低之后的40-80微秒內// 如果DQ在100次重試內沒有被拉高,同樣認為DHT11沒有正確響應while(!DHT11_DQ_IN() && retry < 100)//DHT會再拉高40-80us{retry++;delay_us(1);}if(retry >= 100) return 1;return 0;}
//檢測DHT11是否響應,1無,0有
uint8_t DHT11_Init(void)
{DHT11_Output_Mode();//DHT11_Rst函數中也執行,但為了確保在復位之前引腳狀態正確,再次設置DHT11_Reset();//重置DHT11return DHT11_Check();//檢測是否DHT11響應
}//讀取一個位1/0
uint8_t DHT11_Read_Bit(void)
{uint8_t retry = 0;while(DHT11_DQ_IN() && retry < 100)//DHT會拉低40-80us{retry++;delay_us(1);}retry = 0;while(!DHT11_DQ_IN() && retry < 100)//DHT會拉低40-80us{retry++;delay_us(1);}// 根據DHT11的通信協議,拉高DQ引腳后會保持一段時間// 對于數據位1,DQ引腳會在50微秒內保持高電平;對于數據位0,DQ引腳會在30微秒內拉低// 取中間值等待40微秒delay_us(40);if(DHT11_DQ_IN()) return 1;else return 0;
}
//讀取一個字節
uint8_t DHT11_ReadByte(void)
{uint8_t i,Dat = 0;for(i = 0; i < 8; i++){Dat <<= 1;Dat |= DHT11_Read_Bit();//Dat某一位或運算上1必定為1,或上0位不變}return Dat;
}
//temp溫度數據范圍0-50度
//humi濕度數據范圍20-90%
//指向存儲溫度數據的uint8_t變量的指針temp,
//指向存儲濕度數據的uint8_t變量的指針humi
//返回值0表示讀取成功,1讀取失敗
uint8_t DHT11_ReadData(uint8_t * temp,uint8_t *humi)
{uint8_t DHT11_Buff[5];//用來存讀取DHT11得到的5個字節數據uint8_t i;DHT11_Reset();//復位DHT11if(DHT11_Check() == 0)//如果存在DHT11,讀取溫濕度數據{for(i = 0;i < 5;i++){DHT11_Buff[i] = DHT11_ReadByte();}//驗證數據的完整性,計算前4個字節的和與第5個字節校驗和進行比較if(DHT11_Buff[0] + DHT11_Buff[1] + DHT11_Buff[2] + DHT11_Buff[3] ==         DHT11_Buff[4]){*temp = DHT11_Buff[2];//溫度整數數據*humi = DHT11_Buff[0];//濕度整數數據//小數部分為0不用讀取}}else{return 1;//讀取失敗}return 0;//存在DHT11
}

DHT11.h

#ifndef  __DHT11_H__
#define	 __DHT11_H__
#include<stdint.h>
#include "delay.h"// DHT11初始化函數,檢測傳感器是否存在
// 返回0表示存在,返回1表示不存在
uint8_t DHT11_Init(void);// 配置DHT11數據引腳為輸入模式
// 用于讀取DHT11發送的數據
void DHT11_Input_Mode(void);// 配置DHT11數據引腳為輸出模式
// 用于向DHT11發送命令信號
void DHT11_Output_Mode(void);// 控制DHT11數據引腳輸出高低電平
// 參數BitValue: 0表示輸出低電平,1表示輸出高電平
void DHT11_DQ_OUT(uint8_t BitValue);// 讀取DHT11數據引腳的電平狀態
// 返回值: 0表示低電平,1表示高電平
uint8_t DHT11_DQ_IN(void);// 發送復位信號給DHT11
// 拉低數據線至少18ms,然后拉高20-40us,啟動DHT11
void DHT11_Reset(void);// 檢測DHT11是否響應復位信號
// 返回0表示DHT11響應正常,返回1表示無響應
uint8_t DHT11_Check(void);// 從DHT11讀取一個位的數據
// 返回值: 讀取到的位值(0或1)
uint8_t DHT11_Read_Bit(void);// 從DHT11讀取一個字節的數據
// 返回值: 讀取到的字節值
uint8_t DHT11_ReadByte(void);// 讀取DHT11的溫濕度數據
// 參數temp: 指向存儲溫度數據的變量的指針(范圍0-50℃)
// 參數humi: 指向存儲濕度數據的變量的指針(范圍20-90%)
// 返回值: 0表示讀取成功,1表示讀取失敗
uint8_t DHT11_ReadData(uint8_t *temp, uint8_t *humi);#endif

?delay.c

#include "delay.h"
#include "stm32f1xx_hal.h"TIM_HandleTypeDef htim3;/*** @brief  初始化定時器3用于延時* @param  無* @retval 無*/
void Delay_Init(void)
{TIM_ClockConfigTypeDef sClockSourceConfig = {0};/* 使能TIM3時鐘 */__HAL_RCC_TIM3_CLK_ENABLE();/* 基礎配置 */htim3.Instance = TIM3;htim3.Init.Prescaler = 72-1;  // 72MHz / 72 = 1MHz,即計數頻率為1MHz,計數周期為1ushtim3.Init.CounterMode = TIM_COUNTERMODE_UP;htim3.Init.Period = 0xFFFF;  // 最大計數值htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim3) != HAL_OK){Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK){Error_Handler();}/* 啟動定時器 */HAL_TIM_Base_Start(&htim3);
}/*** @brief  微秒級延時* @param  nus: 延時的微秒數,范圍:0~65535* @retval 無*/
void delay_us(uint16_t nus)
{uint16_t differ;uint16_t ticks = nus;uint16_t start = __HAL_TIM_GET_COUNTER(&htim3);while(1){uint16_t now = __HAL_TIM_GET_COUNTER(&htim3);if(now < start)differ = now + 65536 - start;  // 處理計數器溢出elsediffer = now - start;if(differ >= ticks)break;}
}/*** @brief  毫秒級延時* @param  nms: 延時的毫秒數* @retval 無*/
void delay_ms(uint16_t nms)
{uint32_t i;for(i = 0; i < nms; i++){delay_us(1000);  // 1ms = 1000us}
}

delay.h

#ifndef __DELAY_H
#define __DELAY_H#include "stm32f1xx_hal.h"void Delay_Init(void);
void delay_us(uint16_t nus);
void delay_ms(uint16_t nms);#endif /* __DELAY_H */

使用步驟:

1、在主函數文件添加包含

#include "dht11.h"
#include "delay.h"

2、初始化dht11和定時器延時,注意要先初始化?? ?Delay_Init();

	Delay_Init();DHT11_Init();

3、通過函數讀取問濕度值

uint8_t temp,humidity ;
DHT11_ReadData(&temp,&humidity);

代碼結束

ai編程提示詞

DHT11使用以下函數獲取溫度和濕度。
//temp溫度數據范圍0-50度
//humi濕度數據范圍20-90%
//指向存儲溫度數據的uint8_t變量的指針temp,
//指向存儲濕度數據的uint8_t變量的指針humi
//返回值0表示讀取成功,1讀取失敗
uint8_t DHT11_ReadData(uint8_t * temp,uint8_t *humi)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/79207.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79207.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/79207.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網頁防篡改與盜鏈防護:實時監控與自動化修復實踐

摘要&#xff1a;針對網頁內容篡改與盜鏈問題&#xff0c;本文基于群聯AI云防護系統&#xff0c;詳解如何通過哈希校驗、實時監控與CDN聯動實現秒級修復&#xff0c;并提供Python與AWS S3集成代碼。 一、網頁安全的核心需求 防篡改&#xff1a;保障頁面內容完整性&#xff0c;…

【4】k8s集群管理系列--harbor鏡像倉庫本地化搭建

一、harbor基本概念 ?Harbor是一個由VMware開源的企業級Docker鏡像倉庫解決方案?&#xff0c;旨在解決企業在容器化應用部署中的痛點&#xff0c;提供鏡像存儲、管理、安全和分發的全生命周期管理?。Harbor擴展了Docker Registry&#xff0c;增加了企業級功能&#xff0c;如…

Docker 安裝 Elasticsearch 8.x

Docker 安裝 Elasticsearch 8.x 前言一、準備工作二、設置容器的目錄結構三、啟動一個臨時的容器來復制配置文件四、復制配置文件到本地目錄五、刪除臨時容器六、創建并運行容器&#xff0c;掛載本地目錄七、修改文件配置監聽端口八、端口配置&#xff1a;Host 網絡模式 vs Por…

C#: 用Libreoffice實現Word文件轉PDF

現實場景中要實現Word格式轉PDF格式還是比較常見的。 如果要用開源的組件&#xff0c;只有用Libreoffice了。 一、下載安裝Libreoffice 先進入如下鏈接&#xff0c;找到最新版本和匹配的操作系統來安裝。 官網試過&#xff0c;下載是能下載&#xff0c;但安裝了用不了&…

MoogDB數據庫日常維護技巧與常見問題解析

在當今的數據驅動世界中&#xff0c;數據庫作為信息存儲與管理的核心組件&#xff0c;扮演著舉足輕重的角色。MoogDB作為一款高性能、易擴展的數據庫解決方案&#xff0c;越來越受到開發者和企業的青睞。為了確保MoogDB的穩定性與高性能&#xff0c;定期的日常維護及對常見問題…

JAVA多線程的幾種實現方式

?1. 繼承 Thread 類? ?原理?&#xff1a;通過繼承 Thread 類并重寫 run() 方法定義線程任務&#xff0c;調用 start() 啟動線程?。?代碼示例?&#xff1a; public class MyThread extends Thread {Overridepublic void run() {System.out.println("線程 " g…

爬蟲(基本知識介紹,urllib庫的說明)

爬蟲 爬蟲基礎&#xff08;一些基本原理的梳理&#xff09; scheme://[username:password]hostname[:port][/path][;parameters][?query][#fragment] 注&#xff1a; parameters 和 query 混用&#xff0c;并且現在 query 用的多 ?query 查詢 &#xff0c;用來查詢某類資源…

探秘串口服務器廠家:背后的故事與應用

在科技飛速發展的今天&#xff0c;串口服務器作為連接串口設備與網絡的橋梁&#xff0c;在工業自動化、智能交通、智能家居等眾多領域發揮著關鍵作用。你是否好奇&#xff0c;那些生產串口服務器的廠家究竟有著怎樣的故事&#xff1f;它們的產品背后又蘊含著怎樣的原理呢&#…

工廠能耗系統智能化解決方案 —— 安科瑞企業能源管控平臺

安科瑞顧強 政策背景與“雙碳”戰略驅動 2025年《政府工作報告》明確提出“單位國內生產總值能耗降低3%左右”的目標&#xff0c;要求通過產業結構升級&#xff08;如高耗能行業技術革新或轉型&#xff09;、能源結構優化&#xff08;提高非化石能源占比&#xff09;及數字化…

BI面向模型開發和面向報表開發,有什么區別?

在數字化時代&#xff0c;商業智能&#xff08;BI&#xff09;已成為企業決策不可或缺的工具。BI項目實施時&#xff0c;通常有兩種開發模式&#xff1a;面向模型開發和面向報表開發。雖然兩者都旨在通過數據驅動決策&#xff0c;但在開發邏輯、目標價值和技術路徑上存在顯著差…

OpenHarmony人才認證證書

OpenHarmony人才認證體系目前支持初級工程師認證&#xff0c;要求了解OpenHarmony開源項目、生態進展及系統移植等基礎知識&#xff0c;熟練掌握OpenHarmony的ArkUI、分布式軟總線、分布式硬件、分布式數據管理等基礎能力使用&#xff0c;具備基礎的開發能力。 考試流程可參考O…

映射網絡路路徑和ftp路徑原理是什么,如何使用,有什么區別

文章目錄 一、原理1. 映射網絡路徑2. FTP路徑 二、使用方法1. 映射網絡路徑2. FTP路徑 三、主要區別1. 協議與功能2. 安全性與權限3. 適用場景 四、如何選擇&#xff1f;五、注意事項 映射網絡路徑&#xff08;如SMB/CIFS或NFS&#xff09;和FTP路徑&#xff08;FTP/FTPS/SFTP&…

Windows 圖形顯示驅動開發-WDDM 1.2功能—Windows 8 中的 DirectX 功能改進(一)

Windows 8包括 Microsoft DirectX 功能改進&#xff0c;使開發人員、最終用戶和系統制造商受益。 功能改進在以下幾個方面&#xff1a; 像素格式 (5551、565、4444) &#xff1a;在低功耗硬件配置下&#xff0c;DirectX 應用程序的性能更高。雙精度著色器功能&#xff1a;高級…

GitHub 趨勢日報 (2025年04月15日)

本日報由 TrendForge 系統生成 https://trendforge.devlive.org/ &#x1f4c8; 今日整體趨勢 Top 10 排名項目名稱項目描述今日獲星總星數語言1yeongpin/cursor-free-vip[Support 0.48.x]&#xff08;Reset Cursor AI MachineID & Auto Sign Up / In & Bypass Higher…

2025年推薦使用的開源大語言模型top20:核心特性、選擇指標和開源優勢

李升偉 編譯 隨著人工智能技術的持續發展&#xff0c;開源大型語言模型&#xff08;LLMs&#xff09;正變得愈發強大&#xff0c;使最先進的AI能力得以普及。到2025年&#xff0c;開源生態系統中涌現出多個關鍵模型&#xff0c;它們在各類應用場景中展現出獨特優勢。 大型語言…

回收鍍錫廢水的必要性(筆記)

鍍錫廢水若直接排放&#xff0c;將對環境、經濟和社會造成多重危害&#xff0c;其回收處理具有迫切性和深遠意義。以下從環境、資源、法規、技術與實踐、可持續發展五大維度展開分析&#xff1a; 一、環境危害的緊迫性&#xff1a;重金屬與污染物的致命威脅 成分復雜&#xf…

14.2 - VDMA彩條顯示實驗之動態時鐘

文章目錄 1 實驗任務2 系統框圖3 硬件設計4 軟件設計4.1 dynclk_api.h文件4.2 math_compat.h文件4.3 dynclk_api.c文件4.4 main.c文件 1 實驗任務 參見14.1。 2 系統框圖 參見14.1。 3 硬件設計 注意事項&#xff1a;基于14.1做如下改動 使能Clocking Wizard IP核的Dynam…

在邊緣端進行tensorflow模型的部署(小白初探)

1.配置tensorflow的環境 &#xff08;我是安裝GPU版本的&#xff09; 建議參考這個博主的文章&#xff0c;確實非常快速&#xff01; 十分鐘安裝Tensorflow-gpu2.6.0本機CUDA12 以及numpymatplotlib各包版本協調問題_tensorflow cuda12-CSDN博客 2.學習自制數據集 &#xf…

windows下使用nginx + waitress 部署django

架構介紹 linux一般采用nginx uwsgi部署django&#xff0c;在Windows下&#xff0c;可以取代uwsgi的選項包括Waitressa、Daphnea、Hypercoma和Gunicorna(通過WSLa 運行)。windows服務器一般采用nginx waitress 部署django&#xff0c;,他們的關系如下 django是WEB應用…

利用pnpm patch命令實現依賴包熱更新:精準打補丁指南

需求場景 在Element Plus的el-table組件二次開發中&#xff0c;需新增列顯示/隱藏控件功能。直接修改node_modules源碼存在兩大痛點&#xff1a; 團隊協作時修改無法同步 依賴更新導致自定義代碼丟失 解決方案選型 通過patch-package工具實現&#xff1a; &#x1f4e6; 非…