温湿度传感器DATA引脚在程序中设置为PC0,可以根据自己的需要更改GPIO口。
下面是通讯图片
具体看DHT11手册
一共有两个文件.C和.H
H文件内容
#ifndef TEMP_H_ #
define TEMP_H_
#include "stm32f4xx.h"
#define DHT11_DATA_L (GPIOC ->ODR &= ~(1 << 0)) #define DHT11_DATA_H (GPIOC ->ODR |= (1 << 0)) #define DHT11_DATA (GPIOC ->IDR & (1 << 0))
void DHT11_OUT1();//输出
void DHT11_IN();//输入
u8 DHT11_Start_ACK();
u8 DHT11_Read_byte();
u8 DHT11_Read_data(double *temp,double *humi);
#endif
.C文件内容
#include <stm32f4xx.h>
#include "DHT11.h"
#include "TIM6.h"
/*
函数功能:GPIO输出配置
函数参数:
返 回 值:
说 明:PC0 -DATA
*/
void DHT11_OUT1()
{
//时钟使能
RCC->AHB1ENR |= (1 << 2);
//设置GPIO工作模式
GPIOC->MODER &= ~(3 << 0);
GPIOC->MODER |= (1 << 0);
//设置输出模式(TW)
GPIOC->OTYPER &= ~(1 << 0);
//速度(50MHZ)
GPIOC->OSPEEDR &= ~(0x3 << 0);
GPIOC->OSPEEDR |= (0x2 << 0);
//设置上下拉(上)
GPIOC->PUPDR &= ~(0x3 << 0);
GPIOC->PUPDR |= (0x1 << 0);
TIM6_delayms(1000);
//设置初始状态(空闲状态)
GPIOC ->ODR |= (1 << 0);
}
/*
函数功能:GPIO输入配置
函数参数:
返 回 值:
说 明:PC0 -DATA
*/
void DHT11_IN()
{
RCC->AHB1ENR |= (1 << 2);
//设置GPIO工作模式
GPIOC->MODER &= ~(3 << 0);
GPIOC->PUPDR &= ~(0x3 << 0);
GPIOC->PUPDR |= (0x1 << 0);
}
/*
函数功能:DHT11 开始信号 & 接收应答
函数参数:
返 回 值:0:有应答 1:无应答
说 明:
*/
u8 DHT11_Start_ACK()
{
u8 overtime = 0;
//设置GPIO为输出模式
DHT11_OUT1();
//拉低总线
DHT11_DATA_L;
// (GPIOC->ODR &= ~(1 << 0));
//延时18ms以上
TIM6_delayms(20);
//拉高总线
DHT11_DATA_H;
// (GPIOC->ODR |= (1 << 0));
//切换为输入模式
DHT11_IN();
//等待应答
while(DHT11_DATA)
{
TIM6_delayus(1);
overtime ++;
if(overtime > 50)
return 1;
}
//等待应答结束
overtime = 0;
while(!DHT11_DATA)
{
TIM6_delayus(1);
overtime ++;
if(overtime > 90)
return 1;
}
return 0;
}
/*
函数功能:DHT11 接收一个字节
函数参数:
返 回 值:接收到的数据
说 明:
*/
u8 DHT11_Read_byte()
{
u8 data = 0;
u8 i;//循环变量
for(i=0;i<8; i++)
{
//等待时隙结束
while(!DHT11_DATA);
//判断当前位是0还是1
TIM6_delayus(40);
if(DHT11_DATA)
{
data |= (0x80 >> i);
// TIM6_delayus(30);
}
while(DHT11_DATA);
}
return data;
}
/*
函数功能:DHT11 读取温湿度数据
函数参数:double *temp:温度存储单元
double *humi:湿度存储单元
返 回 值:0:采集成功 1:采集失败
说 明:
*/
u8 DHT11_Read_data(double *temp,double *humi)
{
u8 data[5];
u8 ack;
ack = DHT11_Start_ACK();
//发送开始信号并接收应答
if(ack != 0)
{
return 1;//应答错误
}
//等待接收数据
while(DHT11_DATA);
//接收5个数据
data[0] = DHT11_Read_byte();
data[1] = DHT11_Read_byte();
data[2] = DHT11_Read_byte();
data[3] = DHT11_Read_byte();
data[4] = DHT11_Read_byte();
//校验数据
if(data[4] != ((data[0]+data[1]+data[2]+data[3]) & 0xFF))
return 1;//
//计算温湿度值
*temp = data[2] + data[3] / 10.0;
*humi = data[0] + data[1] / 10.0;
return 0;
}
main文件内容
需要声明头文件
通过串口打印出温度和湿度值
if(DHT11_Read_data(&humi_val,&temp_val) == 0)
{
printf("humi = %5.2f temp=%5.2f\r\n",humi_val,temp_val);
}
else
{
printf("humi temp read error\r\n");
}
获取到的数据
S
网友评论