温湿度传感器 DHT11
1. 硬件连接

2. CubeMX生成代码
MCU 的GPIO的状态 
在这里我们把IO配置成开漏,这样既能输入,也能输出。驱动靠外部的上拉电阻,在温湿度传感器的data PIN 上有一个上拉电阻提供驱动能力。

3. 编写代码
串口配置代码
c
#include <stdio.h>
//重定向c库函数printf到串口USARTx,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口USARTx */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return (ch);
}
//重定向c库函数scanf到串口USARTx,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
int ch;
/* 等待串口输入数据 */
while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET);
HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return (ch);
}us 延时函数, 注意:此代码只能运行在--->主频72M,F103c8t6 。更换 芯片/频率 则有可能失效,导致通信异常!!!
C
void delay_us(uint32_t time)
{
time *= 10;
while(time)
time--;
}温湿度模块控制函数
C
#define DHT11_PIN GPIO_PIN_0
#define DHT11_IO GPIOA
void DHT11_Start()
{
HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_RESET);
HAL_Delay(20); //拉低总线至少 18ms
HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_SET);
while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN)); //上一步将总线设为高电平,等待DHT11响应低电平
while(!HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN)); //上一步DHT11响应低电平,等待DHT11拉高总线
while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN)); //上一步DHT11拉高了总线,等待DHT11拉低总线,开始传送数据
}
uint8_t DHT_Read_Byte(void) //从DHT11读取一位(8字节)信号
{
uint8_t i;
uint8_t ReadData = 0; //ReadData用于存放8bit数据,即8个单次读取的1bit数据的组合
uint8_t temp; //临时存放信号电平(0或1)
for(i=0;i<8;i++){
while(!HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));
delay_us(50);
if(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN) == 1){
temp = 1;
while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));
}else{
temp = 0;
}
ReadData = ReadData << 1;
ReadData |= temp;
}
return ReadData;
}
void DHT_Read()
{
uint8_t i;
uint8_t Data[6] = {0};
DHT11_Start();
for(i= 0;i < 5;i++){
Data[i] = DHT_Read_Byte();
}
if((Data[0]+Data[1]+Data[2]+Data[3])==Data[4])
{
float result = Data[0] + (float)Data[1] / 10.0f;
printf("湿度:%.1f ,\n", result);
result = Data[2] + (float)Data[3] / 10.0f;
printf("温度:%.1f\r\n", result);
}else{
printf("ERROR DATA\r\n");
}
HAL_Delay(2000);
}主函数
C
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
DHT_Read();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}4. 后记
- 代码中使用了开漏的GPIO配置方式,实现了读写功能,无需重新初始化GPIO来实现读写功能。
- 代码中的浮点数仅显示一位小数,显示温湿度。如果位数超过,则显示异常。