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