欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

外設(shè)驅(qū)動(dòng)庫(kù)開(kāi)發(fā)筆記15:DHT11溫濕度傳感器驅(qū)動(dòng) - 新聞資訊 - 云南小程序開(kāi)發(fā)|云南軟件開(kāi)發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開(kāi)發(fā)/軟件開(kāi)發(fā)

知識(shí)

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!

您當(dāng)前位置>首頁(yè) » 新聞資訊 » 技術(shù)分享 >

外設(shè)驅(qū)動(dòng)庫(kù)開(kāi)發(fā)筆記15:DHT11溫濕度傳感器驅(qū)動(dòng)

發(fā)表時(shí)間:2020-10-19

發(fā)布人:葵宇科技

瀏覽次數(shù):89

DS18B20一樣DHT11也是采用單總線,但所不同的是DHT11可同時(shí)實(shí)現(xiàn)溫度和濕度的檢測(cè)。在我們的產(chǎn)品中經(jīng)常使用它來(lái)檢測(cè)環(huán)境的溫濕度信息。這一篇我們將設(shè)計(jì)并封裝DHT11的驅(qū)動(dòng)程序,以方便重復(fù)使用。

1、功能概述

DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號(hào)輸出的溫濕度復(fù)合傳感器。它應(yīng)用專用的數(shù)字模塊采集技術(shù)和溫濕度傳感技術(shù),確保產(chǎn)品具有極高的可靠性與卓越的長(zhǎng)期穩(wěn)定性。

1.1、硬件描述

傳感器包括一個(gè)電阻式感濕元件和一個(gè)NTC測(cè)溫元件,并與一個(gè)高性能8位單片機(jī)相連接。因此該產(chǎn)品具有品質(zhì)卓越、超快響應(yīng)、抗干擾能力強(qiáng)、性價(jià)比極高等優(yōu)點(diǎn)。每個(gè)DHT11傳感器都在極為精確的濕度校驗(yàn)室中進(jìn)行校準(zhǔn)。校準(zhǔn)系數(shù)以程序的形式儲(chǔ)存在OTP內(nèi)存中,傳感器內(nèi)部在檢測(cè)信號(hào)的處理過(guò)程中要調(diào)用這些校準(zhǔn)系數(shù)。單線制串行接口,使系統(tǒng)集成變得簡(jiǎn)易快捷。超小的體積、極低的功耗,信號(hào)傳輸距離可達(dá)20米以上,使其成為各類應(yīng)用甚至最為苛刻的應(yīng)用場(chǎng)合的最佳選擇。產(chǎn)品為4針單排引腳封裝。

DHT11的供電電壓為 35.5V。傳感器上電后,要等待 1s 以越過(guò)不穩(wěn)定狀態(tài)在此期間無(wú)需發(fā)送任何指令。電源引腳(VDDGND)之間可增加一個(gè)100nF 的電容,用以去耦濾波。

1.2、通訊接口

DHT11傳感器單總線通訊建議連接線長(zhǎng)度短于20米時(shí)用5K上拉電阻,大于20米時(shí)根據(jù)實(shí)際情況使用合適的上拉電阻。連線圖如下:

DATA用于微處理器與DHT11之間的通訊和同步,采用單總線數(shù)據(jù)格式,一次通訊時(shí)間4ms左右,數(shù)據(jù)分小數(shù)部分和整數(shù)部分,具體格式在下面說(shuō)明,當(dāng)前小數(shù)部分用于以后擴(kuò)展,現(xiàn)讀出為零。一次完整的數(shù)據(jù)傳輸為40bit,高位在前。數(shù)據(jù)格式:8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù)+8bi溫度整數(shù)數(shù)據(jù)+8bit溫度小數(shù)數(shù)據(jù)+8bit校驗(yàn)和。

其中,在數(shù)據(jù)傳送正確時(shí),校驗(yàn)和數(shù)據(jù)等于“8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù)+8bi溫度整數(shù)數(shù)據(jù)+8bit溫度小數(shù)數(shù)據(jù)所得結(jié)果的末8位。

用戶MCU發(fā)送一次開(kāi)始信號(hào)后,DHT11從低功耗模式轉(zhuǎn)換到高速模式,等待主機(jī)開(kāi)始信號(hào)結(jié)束后,DHT11發(fā)送響應(yīng)信號(hào),送出40bit的數(shù)據(jù),并觸發(fā)一次信號(hào)采集,用戶可選擇讀取部分?jǐn)?shù)據(jù)。通訊過(guò)程如下圖所示:

從模式下,DHT11接收到開(kāi)始信號(hào)觸發(fā)一次溫濕度采集,如果沒(méi)有接收到主機(jī)發(fā)送開(kāi)始信號(hào),DHT11不會(huì)主動(dòng)進(jìn)行溫濕度采集。采集數(shù)據(jù)后轉(zhuǎn)換到低速模式。

2、驅(qū)動(dòng)設(shè)計(jì)與實(shí)現(xiàn)

我們已經(jīng)了解了DHT11溫濕度傳感器的相關(guān)信息,接下來(lái)我們將設(shè)計(jì)并實(shí)現(xiàn)DHT11溫濕度傳感器的驅(qū)動(dòng)程序。

2.1、對(duì)象定義

在使用一個(gè)對(duì)象之前我們需要獲得這個(gè)對(duì)象。同樣的我們想要操作DHT11溫濕度傳感器就需要先定義DHT11溫濕度傳感器的對(duì)象。

2.1.1、對(duì)象的抽象

我們要得到DHT11溫濕度傳感器對(duì)象,需要先分析其基本特性。一般來(lái)說(shuō),一個(gè)對(duì)象至少包含兩方面的特性:屬性與操作。接下來(lái)我們就來(lái)從這兩個(gè)方面思考一下DHT11溫濕度傳感器的對(duì)象。

先來(lái)考慮屬性,作為屬性肯定是用于標(biāo)識(shí)或記錄對(duì)象特征的東西。我們來(lái)考慮DHT11溫濕度傳感器對(duì)象屬性。DHT11溫濕度傳感器并沒(méi)有標(biāo)識(shí)設(shè)備區(qū)別的特性,只有溫度和濕度信息可以表示當(dāng)前的工作狀態(tài)我們將其作為屬性。

接著我們還需要考慮DHT11溫濕度傳感器對(duì)象的操作問(wèn)題。我們知道DHT11溫濕度傳感器采用的是單總線。單總線就需要控制總線的輸入輸出方向,而且這對(duì)這條總線在不同的輸入輸出方向,我們需要讀數(shù)據(jù)和寫(xiě)數(shù)據(jù),而這些操作都依賴于硬件平臺(tái),所以我們將他們定義為DHT11溫濕度傳感器對(duì)象的操作。處于時(shí)序控制的需要,我們需要延時(shí)操作函數(shù),而在不同的軟硬件平臺(tái)延時(shí)操作會(huì)有差異,我們也將其作為對(duì)象的操作。

根據(jù)上述我們對(duì)DHT11溫濕度傳感器的分析,我們可以定義DHT11溫濕度傳感器的對(duì)象類型如下:

/* 定義DHT11對(duì)象類型 */
typedef struct Dht11Object {
       float temperature;             //溫度值
       float humidity;                         //濕度值
      
       uint8_t (*SetPinOutValue)(DhtPinValueType setValue);//設(shè)置DHT11引腳的輸出值
       uint8_t (*ReadPinBit)(void);//讀取引腳電平
       void (*SetPinDirection)(DHT11IOModeType mode);//設(shè)置引腳的輸入輸出方向
      
       void (*Delayms)(volatile uint32_t nTime);      /*實(shí)現(xiàn)ms延時(shí)操作*/
       void (*Delayus)(volatile uint32_t nTime);      /*實(shí)現(xiàn)us延時(shí)操作*/
}Dht11ObjectType;

2.1.2、對(duì)象初始化

我們知道,一個(gè)對(duì)象僅作聲明是不能使用的,我們需要先對(duì)其進(jìn)行初始化,所以這里我們來(lái)考慮DHT11溫濕度傳感器對(duì)象的初始化函數(shù)。一般來(lái)說(shuō),初始化函數(shù)需要處理幾個(gè)方面的問(wèn)題。一是檢查輸入?yún)?shù)是否合理;二是為對(duì)象的屬性賦初值;三是對(duì)對(duì)象作必要的初始化配置。據(jù)此我們?cè)O(shè)計(jì)DHT11溫濕度傳感器對(duì)象的初始化函數(shù)如下:

/*DHT11初始化操作*/
DHT11ErrorType InitializeDHT11(Dht11ObjectType *dht,                //需要初始化對(duì)象
                               Dht11SetPinOutValueType setPinStatus,//設(shè)置總線輸出值
                               Dht11ReadPinBitType getPinStatus,    //讀取總線輸入值
                               Dht11SetPinModeType mode,            //配置總線的輸入輸出模式
                               Dht11DelayType delayms,              //毫秒延時(shí)
                               Dht11DelayType delayus                //微秒延時(shí)
                               )
{
  if((dht==NULL)||(setPinStatus==NULL)||(getPinStatus==NULL)||(mode==NULL)||(delayms==NULL)||(delayus==NULL))
  {
      return DHT11_InitError;
  }
  dht->SetPinOutValue=setPinStatus;
  dht->ReadPinBit=getPinStatus;
  dht->SetPinMode=mode;
  dht->Delayms=delayms;
  dht->Delayus=delayus;
      
  dht->humidity=0.0;
  dht->temperature=0.0;
      
  ResetDHT11(dht);
  return CheckDHT11Status(dht);
}

2.2、對(duì)象操作

我們已經(jīng)完成了DHT11溫濕度傳感器對(duì)象類型的定義和對(duì)象初始化函數(shù)的設(shè)計(jì)。但我們的主要目標(biāo)是獲取對(duì)象的信息,接下來(lái)我們還要實(shí)現(xiàn)面向DHT11溫濕度傳感器的各類操作。

2.2.1、啟動(dòng)數(shù)據(jù)通訊

DHT11溫濕度傳感器上電后,總線空閑狀態(tài)為高電平,主機(jī)把總線拉低等待DHT11響應(yīng),主機(jī)把總線拉低必須大于18毫秒,保證DHT11能檢測(cè)到起始信號(hào)。DHT11接收到主機(jī)的開(kāi)始信號(hào)后,等待主機(jī)開(kāi)始信號(hào)結(jié)束,然后發(fā)送80us低電平響應(yīng)信號(hào)。主機(jī)發(fā)送開(kāi)始信號(hào)結(jié)束后,延時(shí)等待20-40us后, 讀取DHT11的響應(yīng)信號(hào),主機(jī)發(fā)送開(kāi)始信號(hào)后,可以切換到輸入模式,或者輸出高電平均可, 總線由上拉電阻拉高。啟動(dòng)數(shù)據(jù)通訊的時(shí)序圖如下:

/*復(fù)位DHT11,開(kāi)始通訊*/
static void ResetDHT11(Dht11ObjectType *dht)
{
  dht->SetPinMode(DHT11_Out);                 //設(shè)置為輸出方式
  dht->SetPinOutValue(DHT11_Reset);           //將引腳點(diǎn)位拉低
  dht->Delayms(20);                           //拉低至少18ms
  dht->SetPinOutValue(DHT11_Set);             //拉高
  dht->Delayus(30);                           //主機(jī)拉高20至40us
}

DHT11傳感器的DATA引腳檢測(cè)到外部信號(hào)有低電平時(shí),等待外部信號(hào)低電平結(jié)束,延遲后DHT11 DATA引腳處于輸出狀態(tài),輸出80微秒的低電平作為應(yīng)答信號(hào),緊接著輸出 80 微秒的高電平通知外設(shè)準(zhǔn)備接收數(shù)據(jù),微處理器的 I/O 此時(shí)處于輸入狀態(tài),檢測(cè)到 I/O 有低電平(DHT11 回應(yīng)信號(hào))后,等待80微秒的高電平后的數(shù)據(jù)接收。

/*等待DHT11的回應(yīng),返回1:未檢測(cè)到DHT11的存在;返回0:存在*/
static DHT11ErrorType CheckDHT11Status(Dht11ObjectType *dht)
{
  uint8_t retry=0;
  dht->SetPinMode(DHT11_In);                          //設(shè)置為輸入方式
  while(dht->ReadPinBit()&&(retry<100))
  {
    retry++;
    dht->Delayus(1);
  }
  if(retry>=100)
  {
    return DHT11_None;
  }
  retry=0;
  while(!dht->ReadPinBit()&&(retry<100))
  {
    retry++;
    dht->Delayus(1);
  }
  if(retry>=100)
  {
    return DHT11_None;
  }
  return DHT11_NoError; 
}

2.2.2、讀取數(shù)據(jù)位

當(dāng)主機(jī)變?yōu)檩斎肽J胶?#xff0c;檢測(cè)到總線為低電平,說(shuō)明DHT11發(fā)送響應(yīng)信號(hào),DHT11發(fā)送響應(yīng)信號(hào)后,再把總線拉高80us,準(zhǔn)備發(fā)送數(shù)據(jù),每一bit數(shù)據(jù)都以50us低電平時(shí)隙開(kāi)始,高電平的長(zhǎng)短定了數(shù)據(jù)位是“0”還是“1”。表示0”“1”的時(shí)序圖如下所示:

/*從DHT11讀取一個(gè)位,返回值:1/0*/
static uint8_t ReadBitFromDHT11(Dht11ObjectType *dht)               
{
  uint8_t retry=0;
  /*等待變?yōu)榈碗娖?/
  while(dht->ReadPinBit()&&(retry<100))
  {
    retry++;
    dht->Delayus(1);
  }
  retry=0;
  /*等待變高電平*/
  while(!dht->ReadPinBit()&&(retry<100))
  {
    retry++;
    dht->Delayus(1);
  }
  dht->Delayus(40);               //延時(shí)判斷此位是0還是1
 
  return dht->ReadPinBit();
}

當(dāng)最后一bit數(shù)據(jù)傳送完畢后,DHT11拉低總線50us,隨后總線由上拉電阻拉高進(jìn)入空閑狀態(tài)。

3、驅(qū)動(dòng)的使用

我們已經(jīng)實(shí)現(xiàn)了DHT11溫濕度傳感器的驅(qū)動(dòng),接下來(lái)將以此驅(qū)動(dòng)為基礎(chǔ)設(shè)計(jì)了簡(jiǎn)單的測(cè)試應(yīng)用。

3.1、聲明并初始化對(duì)象

使用基于對(duì)象的操作我們需要先得到這個(gè)對(duì)象,所以我們先要使用前面定義的DHT11溫濕度傳感器對(duì)象類型聲明一個(gè)DHT11溫濕度傳感器對(duì)象變量,具體操作格式如下:

Dht11ObjectType dht;

聲明了這個(gè)對(duì)象變量并不能立即使用,我們還需要使用驅(qū)動(dòng)中定義的初始化函數(shù)對(duì)這個(gè)變量進(jìn)行初始化。這個(gè)初始化函數(shù)所需要的輸入?yún)?shù)如下:

Dht11ObjectType *dht,需要初始化對(duì)象

Dht11SetPinOutValueType setPinStatus,設(shè)置總線輸出值

Dht11ReadPinBitType getPinStatus,讀取總線輸入值

Dht11SetPinModeType mode,配置總線的輸入輸出模式

Dht11DelayType delayms,毫秒延時(shí)

Dht11DelayType delayus,微秒延時(shí)

對(duì)于這些參數(shù),對(duì)象變量我們已經(jīng)定義了。剩下的輸入?yún)?shù)就是我們操作中需要的函數(shù),這幾個(gè)函數(shù)需要我們?cè)趹?yīng)用中定義,并將函數(shù)指針作為參數(shù)。這幾個(gè)函數(shù)的類型如下:

typedef uint8_t (*Dht11SetPinOutValueType)(DhtPinValueType setValue);//設(shè)置DHT11引腳的輸出值
typedef uint8_t (*Dht11ReadPinBitType)(void);//讀取引腳電平
typedef void (*Dht11SetPinModeType)(DHT11IOModeType mode);//設(shè)置引腳的輸入輸出方向
typedef void (*Dht11DelayType)(volatile uint32_t nTime);      /*實(shí)現(xiàn)ms延時(shí)操作*/

對(duì)于這幾個(gè)函數(shù)我們根據(jù)樣式定義就可以了,具體的操作可能與使用的硬件平臺(tái)有關(guān)系。我們?cè)?/span>STM32F4HAL庫(kù)環(huán)境下使用,具體函數(shù)定義如下:

//設(shè)置DHT11引腳的輸出值
uint8_t Dht11SetPinOutValue(DhtPinValueType setValue)
{
  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,(GPIO_PinState)setValue);
}

//讀取引腳電平
uint8_t Dht11ReadPinBit(void)
{
  return (uint8_t)HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11);
}

//設(shè)置引腳的輸入輸出方向
void Dht11SetPinMode(DHT11IOModeType mode)
{
  GPIO_InitTypeDef GPIO_InitStruct;
 
  GPIO_InitStruct.Pin = GPIO_PIN_11;
  if(mode==DHT11_In)
  { 
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
  }
  else
  { 
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  } 
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

對(duì)于延時(shí)函數(shù)我們可以采用各種方法實(shí)現(xiàn)。我們采用的STM32平臺(tái)和HAL庫(kù)則可以直接使用HAL_Delay()函數(shù)。微秒延時(shí)函數(shù)則使用我們自己定義的。于是我們可以調(diào)用初始化函數(shù)如下:

InitializeDHT11(&dhtDht11SetPinOutValueDht11ReadPinBitDht11SetPinModeHAL_DelayDelayus);

3.2、基于對(duì)象進(jìn)行操作

我們定義了對(duì)象變量并使用初始化函數(shù)給其作了初始化。接著我們就來(lái)考慮操作這一對(duì)象獲取我們想要的數(shù)據(jù)。我們?cè)隍?qū)動(dòng)中已經(jīng)將獲取數(shù)據(jù)并轉(zhuǎn)換為轉(zhuǎn)換值的比例值,接下來(lái)我們使用這一驅(qū)動(dòng)開(kāi)發(fā)我們的應(yīng)用實(shí)例。

/*獲取數(shù)據(jù)值*/
void GetMeasureDataFromDHT11(void)
{
       float temperature;             //溫度值
       float humidity;                         //濕度值
      
       GetProcessValueFromDHT11(&dht);
      
       temperature=dht.temperature;
       humidity=dht.humidity;
}

4、應(yīng)用總結(jié)

我們已經(jīng)實(shí)現(xiàn)了DHT11溫濕度傳感器的驅(qū)動(dòng),并在此基礎(chǔ)上設(shè)計(jì)了簡(jiǎn)單的驗(yàn)證應(yīng)用。經(jīng)過(guò)測(cè)試,利用驅(qū)動(dòng)我們成功的讀取了溫濕度數(shù)據(jù)。

根據(jù)數(shù)據(jù)手冊(cè)的要求,DHT11溫濕度傳感器上電后要等待1S以越過(guò)不穩(wěn)定狀態(tài)在此期間不能發(fā)送任何指令。

單總線數(shù)據(jù)傳輸時(shí),會(huì)改變總線的輸入輸出方向。在我們的應(yīng)用中,我們修改了對(duì)應(yīng)GPIO引腳的輸入輸出模式。事實(shí)上如果我們?cè)?/span>STM32中使用時(shí),我們可將該引腳配置為開(kāi)漏輸出模式,加上總線的上拉電阻,可以在不修改GPIO的輸入輸出模式的情況下實(shí)現(xiàn)讀寫(xiě)。

源碼下載:https://github.com/foxclever/ExPeriphDriver

歡迎關(guān)注:

相關(guān)案例查看更多