一、溫濕度傳感器
————————————
一般應用的時候,默認將Pin1接VDD Pin4接GND, Pin2作為通信引腳
二、通信程序:串行通信
- 通過一個埠接受來自MCU的命令或者發送給MCU資料,在發送資料的時候,一個完整的資料包含40bit,并且傳感器首先發送高資料位(the sensor sends higher data bit first),
- 資料格式(從左到右發送)

- 校驗格式
求和結果取低八位

正確的舉例校驗:回傳Ture

錯誤的舉例校驗:回傳Fault

三、通信時序圖
1、整體時序圖預覽:
2、 MCU 發送開始信號給 DHT
資料單總線空閑狀態為高電壓電平,當單片機與單片機通信時DHT11開始,單片機的程式將資料單總線電壓電平由高到低,這個程序至少需要18ms才能保證DHT檢測到單片機的信號,然后單片機拉升電壓,等待20-40us的DHT回應

3、DHT 回應 MCU
DHT檢測到啟動信號后,會發出低壓回應信號,持續80us,然后DHT程式將資料單總線電壓由低到高設定為80us,為DHT發送資料做準備,
當資料單總線處于低電壓水平時,這意味著DHT正在發送回應信號,一旦DHT發出回應信號,它拉起電壓并保持80us,為資料傳輸做準備,
DHT向單片機發送資料時,每一位資料都從50us低電壓電平開始,隨后的高電壓電平信號的長度決定了資料位是0還是1,(參見下面的圖4和圖5),


四、程式

DHT11電源為3-5.5V DC,當給傳感器供電時,不要在一秒內給傳感器發送任何指令以通過不穩定狀態,可以在VDD和GND之間增加一個100nF的電容,用于電原始碼波,
1、Mode_Out(uint8_t signal)
//MCU 控制 PA7輸出 “0” 或 “1”
void Mode_Out(uint8_t signal)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
if(!signal)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_7);
}
else
{
GPIO_SetBits(GPIOA, GPIO_Pin_7);
}
}
2、void Mode_In(void)
//控制MCU接收資料
void Mode_In(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
3、void DHT11_Init(void)
void DHT11_Init(void)
{
Mode_Out(1); //開始之前 先拉高信號線
}
4、uint8_t Receive_Data(void)
//接收 1 Byte 資料
uint8_t Receive_Data(void)
{
u8 i,temp=0,j=220;
for(i=0;i<8;i++)
{
while(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7));//50us低電平結束
Delay_us(40);
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7))//為高時
{
temp=(temp<<1)|1;
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)&&(j--));
}
else
{
temp=(temp<<1)|0;
}
}
return temp;
}
5、uint8_t Ready_DHT11(void)
uint8_t Ready_DHT11(void)
{
DHT11_Init();
Mode_Out(0);Delay_us(18000);//18ms
Mode_Out(1);Delay_us(30);//30us
Mode_In();//輸入模式
if(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)) //判斷從機的低電平相應
{
while(!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7));//從機發出的80us低電平相應信號結束
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7));//從機發出的80us高電平信號結束
Humidity_H = Receive_Data(); //接收高8位濕度資料
Humidity_L = Receive_Data(); //接收低8位濕度資料
Temperature_H = Receive_Data(); //接收高8位溫度資料
Temperature_L = Receive_Data(); //接收低8位溫度資料
Check_Out = Receive_Data(); //接收校驗位
}
if(((Humidity_H+Humidity_L+Temperature_H+Temperature_L)&(0xFF))==Check_Out) //校驗
{
return 1;
}
else
{
return 0;
}
}
6、用到的延時
void Delay_us(u32 nTime)
{
SysTick_Config(SystemCoreClock/1000000);
DelayTiming = nTime;
while(DelayTiming != 0);
}
void SysTick_Handler(void)
{
if(DelayTiming != 0){
DelayTiming--;
}
}
7、main
#include "stm32f10x.h"
#include "bsp_seg.h"
#include "lcd.h"
#include "bsp_dht11.h"
#include <stdio.h>
u32 DelayTiming = 0;
void Delay_Ms(u32 nTime)
{
DelayTiming = nTime;
while(DelayTiming != 0);
}
char txt[20];
int main(void)
{
SysTick_Config(SystemCoreClock/1000000);
STM3210B_LCD_Init();
LCD_Clear(White);
STM3210B_LCD_Init();
SEG_GPIO_Config();
LCD_SetTextColor(White);
LCD_SetBackColor(Blue);
LCD_ClearLine(Line0);
LCD_ClearLine(Line1);
LCD_ClearLine(Line2);
LCD_ClearLine(Line3);
LCD_ClearLine(Line4);
LCD_DisplayStringLine(Line1,(u8*)" SDHT11 DEMO ");
LCD_SetTextColor(Blue);
LCD_SetBackColor(White);
while(1)
{
if(1==Ready_DHT11())
{
sprintf(txt, "Moisture:%2d%%",Humidity_H);
LCD_DisplayStringLine(Line6,txt);
sprintf(txt, "Temperature:%2d",Temperature_H);
LCD_DisplayStringLine(Line8,txt);
SEG_Display(Temperature_H/10,Temperature_H%10,12);
}
Delay_us(1000000);//延時1s
}
}
顯示,只要讀出對應溫度和濕度的整數部分即可
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/264214.html
標籤:其他
