//---定义结构体 typedef struct _DHT11_HandlerType DHT11_HandlerType; //---定义指针结构体 typedef struct _DHT11_HandlerType *pDHT11_HandlerType; //---定义 struct _DHT11_HandlerType { UINT16_T msgWenDu; //---温度 UINT16_T msgShiDu; //---湿度 UINT32_T msgBit; //---端口序号 GPIO_TypeDef *msgPort; //---端口号 void (*msgDelayus)(UINT32_T delay); //---us延时函数 void (*msgDelayms)(UINT32_T delay); //---ms延时函数 UINT8_T (*msgTask)(DHT11_HandlerType *DHT11HandlerType, UINT16_T length, UINT8_T *pVal, UINT8_T msg); //---消息处理函数 }; //---外部调用接口 extern DHT11_HandlerType g_DHT11_0; extern pDHT11_HandlerType pDHT11_0;
//---变量定义 DHT11_HandlerType g_DHT11_0; pDHT11_HandlerType pDHT11_0=&g_DHT11_0; /// //函 数: //功 能: //输入参数: //输出参数: //说 明: // UINT8_T DHT11_Init(DHT11_HandlerType *DHT11HandlerType, void(*msgDelayus)(UINT32_T delay), void(*msgDelayms)(UINT32_T delay)) { #ifdef USE_MCU_STM32 if ((DHT11HandlerType == NULL) || (DHT11HandlerType->msgPort == NULL)) { return ERROR_1; } //---使能端口时钟 GPIOTask_Clock(DHT11HandlerType->msgPort, 1); LL_GPIO_InitTypeDef GPIO_InitStruct; //---GPIO的初始化 GPIO_InitStruct.Pin = DHT11HandlerType->msgBit; //---对应的GPIO的引脚 GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; //---配置状态为输出模式 GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; //---GPIO的速度 GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; //---输出模式---开漏输出 GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; //---上拉使能 //---初始化端口 LL_GPIO_Init(DHT11HandlerType->msgPort, &GPIO_InitStruct); #endif GPIO_OUT_1(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit); //---延时函数 if (msgDelayus != NULL) { DHT11HandlerType->msgDelayus = msgDelayus; } if (msgDelayms != NULL) { DHT11HandlerType->msgDelayms = msgDelayms; } //---消息函数 DHT11HandlerType->msgTask = NULL; return OK_0; } /// //函 数: //功 能: //输入参数: //输出参数: //说 明: // UINT8_T DHT11_DeInit(DHT11_HandlerType *DHT11HandlerType) { #ifdef USE_MCU_STM32 LL_GPIO_DeInit(DHT11HandlerType->msgPort); #endif GPIO_OUT_1(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit); //---消息函数 DHT11HandlerType->msgTask = NULL; return OK_0; } /// //函 数: //功 能: //输入参数: //输出参数: //说 明: // UINT8_T DHT11_RESET(DHT11_HandlerType *DHT11HandlerType) { GPIO_OUT_1(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit); //---主机拉高2us if (DHT11HandlerType->msgDelayus != NULL) { DHT11HandlerType->msgDelayus(2); } GPIO_OUT_0(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit); //---触发开始,总线拉低要大于18ms if (DHT11HandlerType->msgDelayms!=NULL) { DHT11HandlerType->msgDelayms(20); } //---释放总线 GPIO_OUT_1(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit); //主机拉高20~40us;等待DHT11的低电平响应信号 if (DHT11HandlerType->msgDelayus != NULL) { DHT11HandlerType->msgDelayus(30); } } /// //函 数: //功 能: //输入参数: //输出参数: //说 明:1:不存在;0:存在 // UINT8_T DHT11_Check(DHT11_HandlerType *DHT11HandlerType) { UINT8_T count = 0; //---DHT11如果响应的话会拉低总线40~80us while (GPIO_GET_STATE(DHT11HandlerType->msgPort,DHT11HandlerType->msgBit)!=0) { if (DHT11HandlerType->msgDelayus !=NULL) { DHT11HandlerType->msgDelayus(1); } count++; if (count>100) { break; } } if (count>100) { return ERROR_1; } count = 0; //---DHT11高电平数据准备信号再次拉高40~80us while (GPIO_GET_STATE(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit) == 0) { if (DHT11HandlerType->msgDelayus != NULL) { DHT11HandlerType->msgDelayus(1); } count++; if (count > 100) { break; } } if (count > 100) { return ERROR_1; } return OK_0; } /// //函 数: //功 能: //输入参数: //输出参数: //说 明:1:不存在;0:存在 // UINT8_T DHT11_START(DHT11_HandlerType *DHT11HandlerType) { //---触发传输 DHT11_RESET(DHT11HandlerType); //---检测设备 return DHT11_Check(DHT11HandlerType); } /// //函 数: //功 能: //输入参数: //输出参数: //说 明:位数据“0”的格式为: 50 微秒的低电平和 26-28 微秒的高电平; / 位数据“1”的格式为: 50 微秒的低电平加 70微秒的高电平 // UINT8_T DHT11_ReadBit(DHT11_HandlerType *DHT11HandlerType) { UINT8_T count = 0; //---等待变为低电平 while (GPIO_GET_STATE(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit) != 0) { if (DHT11HandlerType->msgDelayus != NULL) { DHT11HandlerType->msgDelayus(1); } count++; if (count > 100) { break; } } count = 0; //---等待变高电平 while (GPIO_GET_STATE(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit) == 0) { if (DHT11HandlerType->msgDelayus != NULL) { DHT11HandlerType->msgDelayus(1); } count++; if (count > 100) { break; } } //---等待40us;数据为0的信号时间为26-28us,1则为70us if (DHT11HandlerType->msgDelayus != NULL) { DHT11HandlerType->msgDelayus(40); } //---读取状态 if (GPIO_GET_STATE(DHT11HandlerType->msgPort, DHT11HandlerType->msgBit) != 0) { return 1; } return 0; } /// //函 数: //功 能: //输入参数: //输出参数: //说 明: // UINT8_T DHT11_ReadByte(DHT11_HandlerType *DHT11HandlerType) { UINT8_T i = 0, _return = 0; for (i=0;i<8;i++) { _return <<= 1; _return |= DHT11_ReadBit(DHT11HandlerType); } return _return; } /// //函 数: //功 能: //输入参数: //输出参数: //说 明: // UINT8_T DHT11_ReadData(DHT11_HandlerType *DHT11HandlerType) { UINT8_T temp[5] = { 0 }; UINT8_T i= 0; for (i=0;i<5;i++) { temp[i] = DHT11_ReadByte(DHT11HandlerType); } //---数据校验 if ((temp[0]+temp[1]+temp[2]+temp[3])!=temp[4]) { return ERROR_1; } //---温度整数部分 DHT11HandlerType->msgWenDu = temp[0]; //---温度小数部分 DHT11HandlerType->msgWenDu = (DHT11HandlerType->msgWenDu<<8)+temp[1]; //---湿度整数部分 DHT11HandlerType->msgShiDu = temp[2]; //---湿度小数部分 DHT11HandlerType->msgShiDu = (DHT11HandlerType->msgShiDu << 8) + temp[3]; return OK_0; }