前言
涵盖之前文章:
- Clion开发STM32之HAL库GPIO宏定义封装(最新版)
- Clion开发stm32之微妙延迟(采用nop指令实现)
- Clion开发STM32之日志模块(参考RT-Thread)
DHT11驱动文件
头文件
/*******************************************************************************
Copyright (c) [scl]。保留所有权利。
******************************************************************************/
#ifndef F1XX_TEMPLATE_MODULE_DHT11_H
#define F1XX_TEMPLATE_MODULE_DHT11_H
#include "sys_core.h"
/**
* @memberof input_mode_set 输入模式配置
* @memberof out_mode_set 输出模式配置
* @memberof send_data 发送数据
* @memberof us_delay 微秒延迟
*/
typedef struct {
void (*input_mode_set)(void);
void (*out_mode_set)(void);
void (*send_data)(uint32_t status);
uint32_t (*read_data)(void);
void (*us_delay)(uint32_t us);
} DHT11_conf_t;
typedef struct {
uint8_t humi_int; //湿度的整数部分
uint8_t humi_deci; //湿度的小数部分
uint8_t temp_int; //温度的整数部分
uint8_t temp_deci; //温度的小数部分
uint8_t check_sum; //校验和
} DHT11_data_t;
void DHT11_conf_set(DHT11_conf_t *cnf);
bool DHT11_Driver_Init(void);
DHT11_data_t *DHT11_Read_TH(void);
#endif //F1XX_TEMPLATE_MODULE_DHT11_H
源文件
/*******************************************************************************
Copyright (c) [scl]。保留所有权利。
******************************************************************************/
#include "dht11/module_dht11.h"
#define DHT11_RESET 0
#define DHT11_SET 1
static DHT11_conf_t *dht11_conf_ptr = NULL;
static DHT11_data_t dht11_data;
#define DHT11_OUT_0 dht11_conf_ptr->send_data(0)
#define DHT11_OUT_1 dht11_conf_ptr->send_data(1)
static uint8_t DHT11_ReadByte(void);
static inline void us_delay(uint32_t us) {
dht11_conf_ptr->us_delay(us);
}
static inline void ms_delay(uint32_t ms) {
while (ms--) us_delay(1);
}
void DHT11_conf_set(DHT11_conf_t *cnf) {
dht11_conf_ptr = cnf;
}
bool DHT11_Driver_Init(void) {
if (dht11_conf_ptr == NULL) return false;
/*输出模式设置*/
dht11_conf_ptr->out_mode_set();
/*输出高*/
DHT11_OUT_1;
return true;
}
/**
* @brief 读取DHT11 数据
* @return 不成功为NULL
*/
DHT11_data_t *DHT11_Read_TH(void) {
if (dht11_conf_ptr == NULL) return NULL;
/*输出模式*/
dht11_conf_ptr->out_mode_set();
/*主机拉低*/
DHT11_OUT_0;
/*延时18ms*/
ms_delay(18);
/*总线拉高 主机延时30us*/
DHT11_OUT_1;
us_delay(30); //延时30us
/*主机设为输入 判断从机响应信号*/
dht11_conf_ptr->input_mode_set();
/*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/
if (dht11_conf_ptr->read_data() == DHT11_RESET) {
/*轮询直到从机发出 的80us 低电平 响应信号结束*/
while (dht11_conf_ptr->read_data() == DHT11_RESET);
/*轮询直到从机发出的 80us 高电平 标置信号结束*/
while (dht11_conf_ptr->read_data() == DHT11_SET);
/*开始接收数据*/
dht11_data.humi_int = DHT11_ReadByte();
dht11_data.humi_deci = DHT11_ReadByte();
dht11_data.temp_int = DHT11_ReadByte();
dht11_data.temp_deci = DHT11_ReadByte();
dht11_data.check_sum = DHT11_ReadByte();
/*读取结束,引脚改为输出模式*/
dht11_conf_ptr->out_mode_set();
/*主机拉高*/
DHT11_OUT_1;
uint8_t result = dht11_data.humi_int + dht11_data.humi_deci + dht11_data.temp_int + dht11_data.temp_deci;
/*检查读取的数据是否正确*/
if (dht11_data.check_sum == result) return &dht11_data;
}
return NULL;
}
/*
* 从DHT11读取一个字节,MSB先行
*/
static uint8_t DHT11_ReadByte(void) {
uint8_t i, temp = 0;
for (i = 0; i < 8; i++) {
/*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/
while (dht11_conf_ptr->read_data() == DHT11_RESET);
/*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
*通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时
*/
us_delay(40); //延时x us 这个延时需要大于数据0持续的时间即可
if (dht11_conf_ptr->read_data() == DHT11_SET)/* x us后仍为高电平表示数据“1” */
{
/* 等待数据1的高电平结束 */
while (dht11_conf_ptr->read_data() == DHT11_SET);
temp |= (uint8_t) (0x01 << (7 - i)); //把第7-i位置1,MSB先行
} else // x us后为低电平表示数据“0”
{
temp &= (uint8_t) ~(0x01 << (7 - i)); //把第7-i位置0,MSB先行
}
}
return temp;
}
测试配置
/*******************************************************************************
Copyright (c) [scl]。保留所有权利。
@brief DHT11 温湿度模块配置
******************************************************************************/
#include "app_conf.h"
#define APP_CONF_ENABLE_DHT11_CNF (1)
#if APP_CONF_ENABLE_DHT11_CNF
#include "dht11/module_dht11.h"
#define DBG_ENABLE
#define DBG_SECTION_NAME "DHT11_CNF"
#define DBG_LEVEL DBG_LOG // DBG_LOG DBG_INFO DBG_WARNING DBG_ERROR
#include "sys_dbg.h"
/*-********************************************DHT11_CNF变量定义******************************************-*/
#define DS18B20_LINE PE6
static DHT11_conf_t dh11_conf;
static stm_pin_define_t *dh11_pin_ptr = NULL;
static void out_mode_set(void) { stm32_pin_define_mode_set(dh11_pin_ptr, pin_mode_output); }
static void input_mode_set(void) { stm32_pin_define_mode_set(dh11_pin_ptr, pin_mode_input); }
static void send_data(uint32_t status) { stm32_pin_define_set(dh11_pin_ptr, status); }
static uint32_t read_data(void) { return stm32_pin_define_read(dh11_pin_ptr); }
/*-********************************************DHT11_CNF_pre_init******************************************-*/
static void DHT11_CNF_pre_init() {
dh11_pin_ptr = stm_get_pin(DS18B20_LINE);
dh11_conf.us_delay = bsp_us_delay_nop;
dh11_conf.out_mode_set = out_mode_set;
dh11_conf.input_mode_set = input_mode_set;
dh11_conf.send_data = send_data;
dh11_conf.read_data = read_data;
DHT11_conf_set(&dh11_conf);
}
sys_pre_init_export(DHT11_CNF, DHT11_CNF_pre_init);
/*-********************************************DHT11_CNF_init******************************************-*/
static void DHT11_CNF_init() {
DHT11_Driver_Init();
}
sys_init_export(DHT11_CNF, DHT11_CNF_init);
/*-***********************************************DHT11_CNF_after_init***************************************-*/
static void DHT11_CNF_after_init() {
DHT11_data_t *th = DHT11_Read_TH();
if (th == NULL) {
LOG_W("DHT11_Read_TH ERROR");
} else {
LOG_D("humi:%d.%d %RH ,temp: %d.%d℃", th->humi_int, th->humi_deci, th->temp_int, th->temp_deci);
}
}
sys_after_init_export(DHT11_CNF, DHT11_CNF_after_init);
/*-**************************************DHT11_CNF内部使用************************************************-*/
#endif //APP_CONF_ENABLE_DHT11_CNF
文章来源地址https://www.toymoban.com/news/detail-612357.html
文章来源:https://www.toymoban.com/news/detail-612357.html
到了这里,关于Clion开发Stm32之温湿度传感器(DHT11)驱动编写的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!