#include "stm32f10x.h" #include "Delay.h" #include "DHT11.h" #include "sys.h" //unsigned char humidity, temperature, check_sum ; //全局变量定义区 //***************************************************************************/ // //uchar i; // uchar U8FLAG,k; // uchar U8count,U8temp; // uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata; // uchar U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp; // uchar U8comdata; // uint ReceiveHighByte; // uint ReceiveLowByte; //***************Global defination for DHT11 end****// void DHT11_PortIN ( void ) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd ( DHT11_IORCC, ENABLE ); //切换为输入口 GPIO_InitStructure.GPIO_Pin = DHT11_DATA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init ( DHT11_PORT, &GPIO_InitStructure ); } void DHT11_PortOUT ( void ) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd ( DHT11_IORCC, ENABLE ); GPIO_InitStructure.GPIO_Pin = ( DHT11_DATA_PIN ); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init ( DHT11_PORT, &GPIO_InitStructure ); } static u8 _us = 0; unsigned char StartDHT11 ( void ) { //主机开始信号 /* 低18ms->高30us->等待dht响应(拉低) */ DHT11_PortOUT(); DHT11_Out = 0; delay_ms ( 18 ); //触发开始,总线拉低要大于18ms DHT11_Out = 1; //释放总线 //delay_us(30); //拉低 20-40uS 等待DHT11的低电平响应信号 //dht响应 /* 正确,拉低(80us) ->拉高(80us)->传送数据 */ DHT11_PortIN(); //改为输入 //实际6 _us = 0; while ( DHT11_In ) //低电平的响应信号,20-40uS { if ( ++_us > 40 ) { return 0; } delay_us ( 1 ); } //实际53 _us = 0; while ( !DHT11_In ) //低电平的响应信号,80us { if ( ++_us > 80 ) { return 0; } delay_us ( 1 ); } //实际54 _us = 0; while ( DHT11_In ) //紧接着是80us的高电平数据准备信号 { if ( ++_us > 80 ) { return 0; } delay_us ( 1 ); } //拉低后DHT11会拉高总线80us,接着会开始传数据 return 1; } /* 传输数据: 1.一次8bit 2. 开始(50us 低)-> 0: 26-28us 高+ (50us 低) = 80us 1: 70us 高+ (50us 低) = 120us 3.判断0/1, 1. 26-28us < n < 26-28us+50us 2. 0us < n < 70us 即, 延时35-40us, 高 = 1,是70us的,需要延时40us 低 = 0,是26-28us的 */ static uint8_t Read_Byte ( void ) { u8 i, temp = 0xff; //开始必须是为低的50us 开始信号 if ( !DHT11_In ) { for ( i = 0; i < 8; i++ ) { //等待高电平,消耗50us _us = 0; while ( !DHT11_In ) { if ( ++_us > 50 ) { return temp; } delay_us ( 1 ); } //等待低电平,真实数据的结束 _us = 0; while ( DHT11_In ) { if ( ++_us > 80 ) { return temp; } delay_us ( 1 ); } if ( _us > 37 ) //35-40us后仍为高电平表示数据“1” { temp |= ( uint8_t ) ( 0x01 << ( 7 - i ) ); //把第7-i位置1 } else //40us后为低电平表示数据“0” { temp &= ( uint8_t ) ~ ( 0x01 << ( 7 - i ) ); //把第7-i位置0 } } } return temp; } uint8_t Read_DHT11 ( DHT11_Data_TypeDef *DHT11_Data ) { uint8_t res; uint8_t check_sum; if ( StartDHT11() ) //判断是否已经响应 { /*开始接收数据*/ DHT11_Data->humi_int = Read_Byte(); DHT11_Data->humi_deci = Read_Byte(); DHT11_Data->temp_int = Read_Byte(); DHT11_Data->temp_deci = Read_Byte(); DHT11_Data->check_sum = Read_Byte(); check_sum = DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int + DHT11_Data->temp_deci; /*检查读取的数据是否正确*/ if ( DHT11_Data->check_sum == check_sum ) { res = SUCCESS; } else { res = ERROR; } } else { res = ERROR; } return res; }