<tbody id="q8owe"></tbody>
  • <rp id="q8owe"><acronym id="q8owe"></acronym></rp>
    <dd id="q8owe"></dd>

      <em id="q8owe"></em>

      <em id="q8owe"><acronym id="q8owe"><u id="q8owe"></u></acronym></em>
      <dd id="q8owe"></dd>
      <tbody id="q8owe"><pre id="q8owe"></pre></tbody>
    1. 電子開發網

      電子開發網電子設計 | 電子開發網Rss 2.0 會員中心 會員注冊
      搜索: 您現在的位置: 電子開發網 >> 電子開發 >> 單片機 >> 正文

      STM32(三十一)DHT11溫濕度傳感器獲取溫濕度數據

      作者:佚名    文章來源:本站原創    點擊數:    更新時間:2023/7/29
      一、傳感器實物圖

      DHT11溫濕度傳感器 

      二、DHT11傳感器應用電路圖:

      DHT11傳感器應用電路圖 

      DHT11傳感器應用電路圖 

       

       通過原理圖可知dht11通過DQ腳和STM32F407ZE06的PG9連接。通過DQ進行數據傳輸,串行接口 (單線雙向),半雙工的工作模式。

      串行接口 (單線雙向)

      DATA 用于微處理器與 DHT11之間的通訊和同步,采用單總線數據格式,一次通訊時間4ms左右,數據分小數部分和整數部分,具體格式在下面說明,當前小數部分用于以后擴展,現讀出為零.操作流程如下:

      • 一次完整的數據傳輸為40bit,高位先出。
      • 數據格式:8bit濕度整數數據+8bit濕度小數數據+8bi溫度整數數據+8bit溫度小數數據+8bit校驗和
      • 數據傳送正確時校驗和數據等于“ 8bit濕度整數數據+8bit濕度小數數據+8bi溫度整數數據+8bit溫度小數數據” 所得結果的末8位。
      三、數據傳輸過程

        用戶MCU發送一次開始信號后,DHT11從低功耗模式轉換到高速模式,等待主機開始信號結束后,DHT11發送響應信號,送出40bit的數據,并觸發一次信號采集,用戶可選擇讀取部分數據.從模式下,DHT11接收到開始信號觸發一次溫濕度采集,如果沒有接收到主機發送開始信號,DHT11不會主動進行溫濕度采集.采集數據后轉換到低速模式。

         

      t1~t2 至少18ms
      t3~t4 20~40us
      t5~t6    80us
      t7~t8    80us
      t9~t10    50us
      t11~t12 26us~28us(表示數據0)
      t13~t14    50us
      t15~t16 70us(表示數據1)

      (1)起始階段:主機(DQ腳PG9)主動發送至少18ms(t1-t2)的低電平(開始信號)此時PG9是輸出模式(MCU給DHT11發),保證DHT11能檢測到起始信號,DHT11檢測到起始信號后,從低功耗模式轉換為高速模式,在拉高延時等待20~40us(t3-t4),此時開始信號結束。

      (2)響應階段:DHT11檢測到起始信號后,發送80us(t5-t6)的低電平響應(此時PG9是輸入模式,由DHT11向MCU發),在拉高延時80us(t7-t8)準備輸出,此時響應結束,準備傳輸數據。

      (3)數據傳輸階段:數據傳輸階段,每一bit數據都以50us低電平(t9-t10)時隙開 ,數據0和數據1的區別在與高電平的時間長短。

        數據0:26us~28us的高電平。(即只要判斷高電平的時間超過30us就是傳輸數據1,否則就是0).

        數據1:70us的的高電平。

       

       四、實驗:通過串口打印出溫濕度數據。

       

        代碼分析:有兩種方式,一種是使用精準延時,還有一種就是while循環。

      //dht11.c文件
      #include "dht11.h" GPIO_InitTypeDef GPIO_InitStruct; u8 buff; void Dht11_Init(void) { //1.初始化時鐘 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE); //2.初始化硬件 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//PG9 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//輸出模式 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//推挽輸出 GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed;//速度 快速 25MHz GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOG,&GPIO_InitStruct); } /***************傳入參數確定是輸出還是輸入**********************/ void pin_mode(GPIOMode_TypeDef mode) { GPIO_InitStruct.GPIO_Mode = mode;//模式切換 GPIO_Init(GPIOG,&GPIO_InitStruct);//加進結構體 } /******************初步配置(開始信號)**************************/ uint8_t start_dht11(void) { //1.設置為輸出模式,并且空閑狀態為高電平 pin_mode(GPIO_Mode_OUT); PGout(9)=1; delay_us(2); //2.主機拉低 至少18ms PGout(9)=0; delay_ms(20); //3.主機拉高 20-40us PGout(9)=1; delay_us(30); //4.設置為輸入模式,進入兩個電平跳變 pin_mode(GPIO_Mode_IN); if(!PGin(9))//if(PGin(9)==0) { //檢測低到高跳變 while(!PGin(9)); //檢測高到底跳變 while(PGin(9)); return 1; } return 0; } /*********************獲取8bit數據*******************/ void get_8bit_data(void) { u8 i=0; for(i=0;i<8;i++) { buff = buff <<1; while(!PGin(9));//過濾低電平時間,確定高電平到來 delay_us(30); if(PGin(9))//如果還是高電平,數據就是1 { buff |= 0x01; } else//低電平的話,數據就是0 { buff &= 0xfe; } while(PGin(9));//過濾剩余的高電平時間 } } /****************獲取溫濕度數據*******************/ uint8_t get_dht11_data(char DataBuf[]) { if(start_dht11()) { get_8bit_data();//獲取的是濕度整數 DataBuf[0] = buff; get_8bit_data();//獲取的是濕度小數 DataBuf[1] = buff; get_8bit_data();//獲取的是溫度整數 DataBuf[2] = buff; get_8bit_data();//獲取的是溫度小數 DataBuf[3] = buff; get_8bit_data();//獲取的是校驗和 DataBuf[4] = buff; } if(DataBuf[4] == DataBuf[0]+DataBuf[1]+DataBuf[2]+DataBuf[3]) { return 1; } else return -1; }

        

      //mian.c文件
      #include "stm32f4xx.h"
      #include "led.h"
      #include "key.h"
      #include "exti.h"
      #include "sys.h"
      #include "tim.h"
      #include "pwm.h"
      #include "uart.h"
      #include "stdio.h"
      #include "dht11.h"
      uint16_t uart1_recv_data;
      //重定向fputc 換個方向,此路不通,屏幕輸出不了就往串口發
      //fputc fputs / fgetc fgets
      int fputc(int ch,FILE *f)
      {
      USART_SendData(USART1,ch);
      while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
      return ch;
      }
      //串口接收中斷
      void USART1_IRQHandler(void)
      {
      //判斷確實進中斷標志
      //if(USART_GetITStatus(USART1, USART_IT_RXNE) !=RESET)//==SET
      if(((USART1->SR) & (0x1<<5)) !=0)//發生中斷 該為由硬件自定置1
      {
      //清楚中斷標志位 往里面寫1 記住一定要清空
      //USART_ClearITPendingBit(USART1,USART_IT_RXNE);//用寄存器方式自己去改
      USART1->SR &= ~(0x1<<5);
      uart1_recv_data = USART_ReceiveData(USART1);
      } 
      }
      int main(void)
      {
      u8 ret;
      char DataBuf[5] = {0};
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC 分組
      SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//滴答定時器8分頻
      LED_Init();
      Key_Init();
      //Exti_Init();
      //Tim_Init();
      //Pwm_Tim14();
      Uart_Init(115200);
      Dht11_Init();
      printf("hello uart1\r\n");
      while(1)
      {
      ret = get_dht11_data(DataBuf);
      if(ret == 1)
      {
      printf("溫度:%d ℃ 濕度:%d\r\n",DataBuf[2],DataBuf[0]); 
      }
      else
      {
      printf("get dht11 failed!");
      }
      delay_s(2);
      }
      return 0;
      }
      
      Tags:STM32單片機,STM32,DHT11,溫濕度傳感器  
      責任編輯:admin
    2. 上一篇文章:
    3. 下一篇文章: 沒有了
    4. 請文明參與討論,禁止漫罵攻擊,不要惡意評論、違禁詞語。 昵稱:
      1分 2分 3分 4分 5分

      還可以輸入 200 個字
      [ 查看全部 ] 網友評論
      關于我們 - 聯系我們 - 廣告服務 - 友情鏈接 - 網站地圖 - 版權聲明 - 在線幫助 - 文章列表
      返回頂部
      刷新頁面
      下到頁底
      晶體管查詢
      亚洲欧美日产在线观看,欧美中字慕日产2,欧美亚洲日产激情四射,日产精品视频一至六区