DHT11_Status_TypeDef DHT11_ReadData(DHT11_Data_TypeDef *data) { uint8_t buffer[5] = {0}; if (DHT11_Start() != DHT11_OK) return DHT11_ERROR; for (uint8_t i = 0; i < 5; i++) buffer[i] = DHT11_ReadByte(); if ((buffer[0] + buffer[1] + buffer[2] + buffer[3]) != buffer[4]) return DHT11_ERROR; data->humidity = buffer[0]; data->temperature = buffer[2]; return DHT11_OK; }
时间: 2024-03-14 13:49:02 浏览: 77
这是一段使用DHT11温湿度传感器读取数据的嵌入式系统代码。其中,DHT11_Start()函数用于启动传感器并进行数据传输,DHT11_ReadByte()函数用于读取传感器返回的单字节数据。读取到的数据存储在buffer数组中,其中前两个元素为湿度数据,后两个元素为温度数据,第五个元素为校验和。最后,通过判断前四个元素的和是否等于第五个元素,来判断数据的正确性。如果数据正确,则将湿度和温度数据分别保存在DHT11_Data_TypeDef结构体的humidity和temperature成员中,并返回DHT11_OK;否则返回DHT11_ERROR。
相关问题
#include "dht11.h" #define DHT11_GPIO_PORT GPIOB #define DHT11_GPIO_PIN GPIO_PIN_8 static void DHT11_DelayUs(uint32_t us) { __HAL_TIM_SET_COUNTER(&htim1, 0); while (__HAL_TIM_GET_COUNTER(&htim1) < us); } static uint8_t DHT11_ReadBit(void) { uint8_t retry = 0; while (HAL_GPIO_ReadPin(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == GPIO_PIN_RESET) { if (++retry > 100) { return DHT11_TIMEOUT; } DHT11_DelayUs(1); } retry = 0; while (HAL_GPIO_ReadPin(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == GPIO_PIN_SET) { if (++retry > 100) { return DHT11_TIMEOUT; } DHT11_DelayUs(1); } return GPIO_PIN_SET; } uint8_t DHT11_ReadData(DHT11_Data_TypeDef *data) { uint8_t buffer[5] = {0}; uint8_t i, j; /* 发送起始信号 */ HAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_RESET); DHT11_DelayUs(18000); HAL_GPIO_WritePin(DHT11_GPIO_PORT, DHT11_GPIO_PIN, GPIO_PIN_SET); DHT11_DelayUs(40); /* 等待应答信号 */ if (HAL_GPIO_ReadPin(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == GPIO_PIN_RESET) { while (HAL_GPIO_ReadPin(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == GPIO_PIN_RESET); while (HAL_GPIO_ReadPin(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == GPIO_PIN_SET); for (i = 0; i < 5; i++) { for (j = 0; j < 8; j++) { if (DHT11_ReadBit() == DHT11_TIMEOUT) { return DHT11_TIMEOUT; } DHT11_DelayUs(30); if (HAL_GPIO_ReadPin(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == GPIO_PIN_SET) { buffer[i] |= (1 << (7 - j)); } } } if ((buffer[0] + buffer[1] + buffer[2] + buffer[3]) == buffer[4]) { data->Humidity = buffer[0]; data->Temperature = buffer[2]; return DHT11_OK; } else { return DHT11_ERROR; } } return DHT11_TIMEOUT; } void DHT11_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* 使能GPIOB时钟 */ __HAL_RCC_GPIOB_CLK_ENABLE(); /* 配置GPIOB8引脚为输入模式 */ GPIO_InitStruct.Pin = DHT11_GPIO_PIN; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct); }
这是一个用于读取DHT11温湿度传感器数据的函数库,包含了初始化函数DHT11_Init()和读取数据函数DHT11_ReadData(),以及一些辅助函数。在读取数据时,函数会发送起始信号,等待应答信号,然后读取40位数据,计算校验和并返回温湿度数据。该函数库需要在使用之前调用DHT11_Init()函数进行初始化。
#include "dht11.h" #include "protocol.h" #include "lcd.h" #include "string.h" #include <stdio.h> #include "gpio.h" #include "usart.h" #define DHT11_DATA_LOW_TIMEOUT 80 #define DHT11_DATA_HIGH_TIMEOUT 90 #define DHT11_RESPONSE_TIMEOUT 40 #define DHT11_BIT_TIMEOUT 60 DHT11_StatusTypeDef DHT11_ReadData(DHT11_Data_TypeDef* data) { uint8_t buffer[5] = {0}; uint8_t i, j; uint32_t count; // 发送开始信号 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET); HAL_Delay(18); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET); // 等待DHT11响应 count = 0; while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_RESET) { count++; if (count > DHT11_RESPONSE_TIMEOUT) { return DHT11_ERROR; } HAL_Delay(1); } count = 0; while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_SET) { count++; if (count > DHT11_RESPONSE_TIMEOUT) { return DHT11_ERROR; } HAL_Delay(1); } // 读取40位数据 for (i = 0; i < 40; i++) { count = 0; while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_RESET) { count++; if (count > DHT11_DATA_LOW_TIMEOUT) { return DHT11_ERROR; } } count = 0; while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_SET) { count++; if (count > DHT11_DATA_HIGH_TIMEOUT) { return DHT11_ERROR; } } buffer[i / 8] <<= 1; if (count > DHT11_BIT_TIMEOUT) { buffer[i / 8] |= 0x01; } } // 验证数据是否正确 if (buffer[4] != (buffer[0] + buffer[1] + buffer[2] + buffer[3])) { return DHT11_ERROR; } // 解析数据 data->humidity = buffer[0]; data->temp_int = buffer[2]; data->temp_dec = buffer[3]; return DHT11_OK; } void text_func_1() { DHT11_Data_TypeDef data; DHT11_ReadData(&data); printf("-->"); printf("%d.%c %d%%",data.temp_int, data.temp_dec, data.humidity); HAL_Delay(1000); if (DHT11_ReadData(&data) == DHT11_OK){ char str[16]; sprintf(str, "T:%d.%dC H:%d%%", data.temp_int, data.temp_dec, data.humidity); HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), HAL_MAX_DELAY); HAL_Delay(1000); } }改错
代码中需要修改的地方:
1. 在 `DHT11_ReadData` 函数中,`buffer[i / 8]` 需要先清零再左移,否则可能导致结果错误。
修改前:`buffer[i / 8] <<= 1;`
修改后:`buffer[i / 8] = 0; buffer[i / 8] |= 0x01 << (7 - (i % 8));`
2. 在 `text_func_1` 函数中,需要判断 `DHT11_ReadData` 函数返回值是否为 `DHT11_OK`,如果不是,则不执行后面的代码。
修改前:
```
DHT11_ReadData(&data);
printf("-->");
printf("%d.%c %d%%",data.temp_int, data.temp_dec, data.humidity);
HAL_Delay(1000);
if (DHT11_ReadData(&data) == DHT11_OK){
char str[16];
sprintf(str, "T:%d.%dC H:%d%%", data.temp_int, data.temp_dec, data.humidity);
HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);
HAL_Delay(1000);
}
```
修改后:
```
if (DHT11_ReadData(&data) == DHT11_OK){
printf("-->");
printf("%d.%c %d%%",data.temp_int, data.temp_dec, data.humidity);
HAL_Delay(1000);
char str[16];
sprintf(str, "T:%d.%dC H:%d%%", data.temp_int, data.temp_dec, data.humidity);
HAL_UART_Transmit(&huart1, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);
HAL_Delay(1000);
}
```
阅读全文