STM32+DHT11溫濕度檢測(cè)

1.DHT11溫濕度檢測(cè)模塊

濕度測(cè)量范圍:20%-95% 濕度測(cè)量誤差-+5%
溫度測(cè)量范圍:0度-50度 溫度測(cè)量誤差:-+2度
引腳:VCC DATE GND
工作電壓 3.3v-5v
輸出形式 數(shù)字輸出

2.溫濕度采用單總線協(xié)議

一、單總線協(xié)議(1-wire)
1.定義:主機(jī)和從機(jī)通過(guò)1根線進(jìn)行通信,在一條總線上可掛接的從器件數(shù)量幾乎不受限制。
2.特點(diǎn):這是由達(dá)拉斯半導(dǎo)體公司推出的一項(xiàng)通信技術(shù)。它采用單根信號(hào)線,既可傳輸時(shí)鐘,又能傳輸數(shù)據(jù),而且數(shù)據(jù)傳輸是雙向的。
3.優(yōu)點(diǎn):?jiǎn)慰偩€技術(shù)具有線路簡(jiǎn)單,硬件開(kāi)銷少,成本低廉,便于總線擴(kuò)展和維護(hù)等。
二、單總線通信過(guò)程
1.初始化
初始化過(guò)程 = 復(fù)位脈沖 + 從機(jī)應(yīng)答脈沖。
主機(jī)通過(guò)拉低單總線480 ~ 960 us產(chǎn)生復(fù)位脈沖,然后釋放總線,進(jìn)入接收模式。主機(jī)釋放總線時(shí),會(huì)產(chǎn)生低電平跳變?yōu)楦唠娖降纳仙兀瑔慰偩€器件檢測(cè)到上升沿之后,延時(shí)15 ~ 60 us,單總線器件拉低總線60 ~ 240 us來(lái)產(chǎn)生應(yīng)答脈沖。主機(jī)接收到從機(jī)的應(yīng)答脈沖說(shuō)明單總線器件就緒,初始化過(guò)程完成。
初始化時(shí)序圖如下所示:

/*
DHT11所用管腳配置
PB9--VCC
輸出模式
*/

void DHT11_OUT(void)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//時(shí)能PB時(shí)鐘
    
    GPIO_InitStruct.GPIO_Pin =GPIO_Pin_9;//PB9管腳
    GPIO_InitStruct.GPIO_Mode =GPIO_Mode_Out_PP;//推挽輸出
    GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;//輸出速度
    GPIO_Init(GPIOB, &GPIO_InitStruct);//GPIOB的初始化
    VCC_H;//總線拉高
}
/*
輸入模式
*/
void DHT11_IN(void)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//時(shí)能PB時(shí)鐘
    
    GPIO_InitStruct.GPIO_Pin =GPIO_Pin_9;//PB9管腳
    GPIO_InitStruct.GPIO_Mode =GPIO_Mode_IN_FLOATING;//浮空輸入
    GPIO_Init(GPIOB, &GPIO_InitStruct);//GPIOB的初始化
}
void DTH11_Config(void)
{
    DHT11_OUT();
    DHT11_IN();
}

2.寫(xiě)間隙
寫(xiě)間隙有兩種,包括寫(xiě)0的時(shí)間隙和寫(xiě)1的時(shí)間隙。
當(dāng)數(shù)據(jù)線拉低后,在15 ~ 60 us的時(shí)間窗口內(nèi)對(duì)數(shù)據(jù)線進(jìn)行采樣。如果數(shù)據(jù)線為低電平,就是寫(xiě)0,如果數(shù)據(jù)線為高電平,就是寫(xiě)1。主機(jī)要產(chǎn)生一個(gè)寫(xiě)1時(shí)間隙,就必須把數(shù)據(jù)線拉低,在寫(xiě)時(shí)間隙開(kāi)始后的15 us內(nèi)允許數(shù)據(jù)線拉高。主機(jī)要產(chǎn)生一個(gè)寫(xiě)0時(shí)間隙,就必須把數(shù)據(jù)線拉低并保持60 us。
寫(xiě)時(shí)間隙時(shí)序圖如下所示:



3.讀時(shí)間隙
當(dāng)主機(jī)把總線拉低是,并保持至少1 us后釋放總線,必須在15 us內(nèi)讀取數(shù)據(jù)。
讀時(shí)間隙時(shí)序圖如下所示:


/*
讀取DHT11的值
*/
void READ_Data(void)
{
    DHT11_OUT();//輸出模式
    VCC_L;
    Delay_ms(20);
    VCC_H;
    Delay_us(30);
    
    DHT11_IN();//輸入模式
    while(RD_DHT11_DATA);//響應(yīng)信號(hào) 等待拉低
    while(!RD_DHT11_DATA);//等待拉高
    while(RD_DHT11_DATA);//等待電平間隙
    //接收數(shù)據(jù)
    for(i=0;i<40;i++)
    {
        while(!RD_DHT11_DATA);//等待電平拉高 接收數(shù)據(jù)
        Delay_us(50);//延時(shí)50 判斷邏輯值
        if(RD_DHT11_DATA)
        {
            if(i<8)
            {
                data1 |=( 1<<(8-i-1));
            }
            if(i>=8&&i<16)
            {
                data2 |=(1<<(16-i-1));
            }
            if(i>=16&&i<24)
            {
                data3 |=(1<<(24-i-1));
            }
            if(i>=24&&i<32)
            {
                data4 |=(1<<(32-i-1));
            }
            if(i>=32&&i<40)
            {
                data0 |=(1<<(40-i-1));
            }
            while(RD_DHT11_DATA);
        }
        
    }
    DHT11_OUT();//輸出模式
    Delay_us(50);
    VCC_H;//總線拉高
}
3.將采集的模擬信號(hào)經(jīng)ADC轉(zhuǎn)換成數(shù)字信號(hào)

設(shè)置PA5為模擬通道輸入引腳:
-開(kāi)啟PA及ADC時(shí)鐘
-設(shè)置端口模式—模擬輸入
-設(shè)置ADC工作模式(使用提供的庫(kù)函數(shù)定義,雖然方便開(kāi)發(fā),但不利于理解內(nèi)部功能)

獲取AD轉(zhuǎn)換值

void Adc_Init(void)
{
    ADC_InitTypeDef ADC_InitStructure; 
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC2    , ENABLE );   //使能ADC2通道時(shí)鐘
 

    RCC_ADCCLKConfig(RCC_PCLK2_Div8);   //設(shè)置ADC分頻因子6 72M/6=12,ADC最大時(shí)間不能超過(guò)14M

    //PA5 作為模擬通道輸入引腳                         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;       //模擬輸入引腳
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

    //ADC_DeInit(ADC2);  //復(fù)位ADC2,將外設(shè) ADC2 的全部寄存器重設(shè)為缺省值

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //ADC工作模式:ADC2和ADC2工作在獨(dú)立模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;//不用掃描模式
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模數(shù)轉(zhuǎn)換工作在單次轉(zhuǎn)換模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //轉(zhuǎn)換由軟件而不是外部觸發(fā)啟動(dòng)
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  //ADC數(shù)據(jù)右對(duì)齊
    ADC_InitStructure.ADC_NbrOfChannel = 1; //順序進(jìn)行規(guī)則轉(zhuǎn)換的ADC通道的數(shù)目
    ADC_Init(ADC2, &ADC_InitStructure); //根據(jù)ADC_InitStruct中指定的參數(shù)初始化外設(shè)ADCx的寄存器   

  
    ADC_Cmd(ADC2, ENABLE);  //使能指定的ADC2
    
    //ADC_ResetCalibration(ADC2);   //使能復(fù)位校準(zhǔn)  
     
    //while(ADC_GetResetCalibrationStatus(ADC2));   //等待復(fù)位校準(zhǔn)結(jié)束
    
    ADC_StartCalibration(ADC2);  //開(kāi)啟AD校準(zhǔn)
 
    while(ADC_GetCalibrationStatus(ADC2));   //等待校準(zhǔn)結(jié)束
 
//  ADC_SoftwareStartConvCmd(ADC2, ENABLE);     //使能指定的ADC2的軟件轉(zhuǎn)換啟動(dòng)功能
}
/*
得到AD轉(zhuǎn)換值
*/
u16 Get_ADC_Data(void)
{
    //設(shè)置指定ADC的規(guī)則組通道,一個(gè)序列,采樣時(shí)間
    ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 1, ADC_SampleTime_239Cycles5 );   //ADC2,ADC通道,采樣時(shí)間為239.5周期                   
  
    ADC_SoftwareStartConvCmd(ADC2, ENABLE);     //使能指定的ADC2的軟件轉(zhuǎn)換啟動(dòng)功能    
     
    while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC ));//等待轉(zhuǎn)換結(jié)束

    return ADC_GetConversionValue(ADC2);    //返回最近一次ADC2規(guī)則組的轉(zhuǎn)換結(jié)果
}
//u16 Get_vlaue()
//{
//  u16 adcvlaue=0;
//  adcvlaue=80*(float)Get_ADC_Data()/4096.0;
//  return adcvlaue;
//}

GitHub代碼連接:
Test-environment/DHT11/DHT11.c

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容