目录
1. DHT11简介
1.1. 连接电路
1.2. 串行接口 (单线双向)
2. cubeMX设置
3. 代码开发
3.1. 实现定时函数
3.2. 打开串口调试
3.4. 测试代码实现
4. 运行效果
1. DHT11简介
1.1. 连接电路
信息如下:
建议连接线长度短于20米时用5K上拉电阻,大于20米时根据实际情况使
用合适的上拉电阻
DHT11的供电电压为 3-5.5V。传感器上电后,要等待 1s 以越过不稳定状态在此
期间无需发送任何指令。电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去
耦滤波。
1.2. 串行接口 (单线双向)
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次
通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数
部分用于以后扩展,现读出为零.操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
2. cubeMX设置
- GPIOE,GPIO_PIN_6,作为DATA接口。推挽输出,上拉电阻。
- 打开定时器TIM6。
- 开启USART1。
3. 代码开发
3.1. 实现定时函数
time.c文件:
/* USER CODE BEGIN 0 */
#include <stdio.h>
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
void delay_us(uint16_t delayValue)
{
uint16_t delayCount=0;
HAL_TIM_Base_Start(&htim6);
__HAL_TIM_SetCounter(&htim6,delayCount);
while(delayCount<delayValue)
{
delayCount=__HAL_TIM_GetCounter(&htim6);
}
HAL_TIM_Base_Stop(&htim6);
}
void delay_ms(uint16_t delayValue)
{
for(int i=0;i<delayValue;i++)
{
delay_us(1000);
}
}
/* USER CODE END 1 */
3.2. 打开串口调试
usart.h文件:
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
usart.c文件:
/* USER CODE BEGIN 1 */
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,1000);
return ch;
}
/* USER CODE END 1 */
3.3. 实现DHT11协议
gpio.h文件:
/* USER CODE BEGIN Private defines */
typedef enum
{
INPUT=0,OUTPUT
}IOMODE;
#define DHT_GPIO_H HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_SET)
#define DHT_GPIO_L HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_RESET)
/* USER CODE END Private defines */
/* USER CODE BEGIN Prototypes */
_Bool readDht11(void);
/* USER CODE END Prototypes */
gpio.c文件:
/* USER CODE BEGIN 0 */
#include "tim.h"
#include <stdio.h>
#include "main.h"
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
uint8_t humiAndTemp[5];
_Bool status=1;
/* USER CODE END 1 */
/* USER CODE BEGIN 2 */
void dht11IOMode(IOMODE ioMode)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6;
if(ioMode==INPUT)
{
GPIO_InitStruct.Mode=GPIO_MODE_INPUT;
GPIO_InitStruct.Pull=GPIO_PULLUP;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}else if(ioMode==OUTPUT)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, GPIO_PIN_SET);
GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull=GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
}
_Bool dht11Start(void)
{
dht11IOMode(OUTPUT);
DHT_GPIO_L;
delay_ms(20);
dht11IOMode(INPUT);
delay_us(30);
uint16_t count;
for(count=0;count<60;count++)
{
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_RESET)
break;
delay_us(2);
}
if(count>=59)
{
LOG("dht11 start fail\n");
return 0;
}
while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_RESET);
while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_SET);
return 1;
}
uint8_t readDht11Byte(void)
{
uint8_t value=0;
uint8_t count=0;
for(uint8_t i=0;i<8;i++)
{
value<<=1;
count=0;
while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_RESET)
{
count++;
if(count>=35)
{
status=0;
return 0;
}
delay_us(2);
}
delay_us(38);
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_SET)
{
value|=1;
}else{
value|=0;
}
count=0;
while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_6)==GPIO_PIN_SET)
{
count++;
if(count>=35)
{
status=0;
return 0;
}
delay_us(2);
}
}
status=1;
return value;
}
_Bool readDht11(void)
{
uint8_t check_value=0;
if(dht11Start()==0)
{
LOG("dht11 start fail\n");
return 0;
}
for(uint8_t i=0;i<5;i++)
{
humiAndTemp[i]=readDht11Byte();
if(status==0)
{
LOG("humiAndTemp[%d] fail\n",i);
return 0;
}
status=1;
if(i!=4)
{
check_value+=humiAndTemp[i];
}
}
if(check_value==humiAndTemp[4])
{
LOG("check_value success,check_value:%d,humiAndTemp[4]:%d\n",check_value,humiAndTemp[4]);
return 1;
}else{
LOG("check_value fail,check_value:%d,humiAndTemp[4]:%d\n",check_value,humiAndTemp[4]);
return 0;
}
}
/* USER CODE END 2 */
3.4. 测试代码实现
main.h文件:
/* USER CODE BEGIN Private defines */
#define OPENLOG
#ifdef OPENLOG
#define LOG(fmt, ...) printf("<%s:%s>:"fmt"\r\n", __FILE__, __FUNCTION__, ##__VA_ARGS__)
#else
#define LOG(fmt, ...)
#endif
/* USER CODE END Private defines */
main.c文件:
/* USER CODE BEGIN 2 */
HAL_Delay(1000);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
while (1)
{
printf("hello world\n");
if(readDht11())
{
printf("readDht11 success\n");
printf("humiAndTemp[0]:%d\n",humiAndTemp[0]);
printf("humiAndTemp[1]:%d\n",humiAndTemp[1]);
printf("humiAndTemp[2]:%d\n",humiAndTemp[2]);
printf("humiAndTemp[3]:%d\n",humiAndTemp[3]);
printf("humiAndTemp[4]:%d\n",humiAndTemp[4]);
uint16_t humi=(humiAndTemp[0]<<8) + humiAndTemp[1];
uint16_t temp=(humiAndTemp[2]<<8) + humiAndTemp[3];
printf("temp:%d.%d\n",temp>>8,temp&0xff);
printf("humi:%d.%d\n",humi>>8,humi&0xff);
}
else
{
printf("readDht11 fail\n");
}
delay_ms(5000);
/* USER CODE END WHILE */
}
4. 运行效果
文章来源:https://www.toymoban.com/news/detail-415672.html
文章来源地址https://www.toymoban.com/news/detail-415672.html
到了这里,关于stm32连接DHT11温湿度传感器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!