Clion开发Stm32之温湿度传感器(DHT11)驱动编写
前言
涵盖之前文章:
- 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 1static 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
相关文章:
Clion开发Stm32之温湿度传感器(DHT11)驱动编写
前言 涵盖之前文章: Clion开发STM32之HAL库GPIO宏定义封装(最新版)Clion开发stm32之微妙延迟(采用nop指令实现)Clion开发STM32之日志模块(参考RT-Thread) DHT11驱动文件 头文件 /*******************************************************************************Copyrig…...
位操作相关的函数(C++)
目录 popcount函数 bitset类模板 __builtin_popcount函数 popcount函数 在C中,std::popcount函数是用来计算一个整数二进制表示中包含的1的个数。不过要注意,这个函数是C20标准引入的,因此在使用之前,要先确保编译器支持C20标…...

arm 函数栈回溯
大概意思就是arm每个函数开始都会将PC、LR、SP以及FP四个寄存器入栈。 下面我们看一下这四个寄存器里面保存的是什么内存 arm-linux-gnueabi-gcc unwind.c -mapcs -w -g -o unwind(需要加上-mapcs才会严格按照上面说的入栈) #include <stdio.h> …...

30个前端开发中常用的JavaScript函数
🧑💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 前言 在前端开发中通常会用到校验函数…...

基于量子同态加密的改进多方量子私有比较
摘要量子同态加密在隐私保护方面具有明显的优势。本文提出了一种改进的基于量子同态加密的多方量子私钥比较协议。首先,引入可信密钥中心,安全辅助加密密钥的分发和解密密钥的更新,同时防止恶意服务器发布虚假结果的攻击;在保证所有参与者得到…...

解决mysqld服务启动失败
原因如下: 1、进程占用 首先查看下mysql进程: ps -aux | grep mysql有进程号占用了,kill 这个进程号 再重启服务 2、所有者和所属组为mysql 查看/usr/local/MySQL/data/mysqld.pid所有者和所属组是否为mysql 原来是权限有问题,…...

【前端知识】React 基础巩固(四十)——Navigate导航
React 基础巩固(四十)——Navigate导航 一、Navigate的基本使用 新建Login页面,在Login中引入Navigate,实现点击登陆按钮跳转至/home路径下: import React, { PureComponent } from "react"; import { Navigate } from "reac…...

文件IO练习
一、用read函数完成文件大小计算 #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main(int argc, const char *argv[]) {int fd open("./1.tx…...
初识FreeRTOS入门,对FreeRTOS简介、任务调度、内存管理、通信机制以及IO操作,控制两个led不同频率闪烁
当代嵌入式系统的开发越来越复杂,实时性要求也越来越高。为了满足这些需求,开发者需要使用实时操作系统(RTOS),其中一个流行的选择是FreeRTOS(Free Real-Time Operating System)。本篇博客将详细…...

STM32CUBUMX配置FLASH(W25Q128)--保姆级教程
———————————————————————————————————— ⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。 ⏩最近在开发一个STM32H723ZGT6的板子,使用STM32CUBEMX做了很多驱动&#x…...

【Golang 接口自动化04】 解析接口返回JSON串
目录 前言 解析到结构体 json数据与struct字段是如何相匹配的呢? 解析到interface Go类型和JSON类型 实例代码 simpleJson 总结 资料获取方法 前言 上一次我们一起学习了如何解析接口返回的XML数据,这一次我们一起来学习JSON的解析方法。 JSO…...
EPPlus与Microsoft.Office.Interop.Excel的使用区别
文章目录 代码的使用区别EPPlus的工作原理Microsoft.Office.Interop.Excel的使用原理代码的使用区别 static void ExportToExcel(List<(string, double, double)> list, string outputFilePath){//Microsoft.Office.Interop.Excel的使用 /* Excel.Application excelAp…...
ncrack工具使用说明
介绍 网络认证破解工具。 Ncrack是用于网络身份验证破解的开源工具。 它设计为使用可适应不同网络情况的动态引擎进行高速并行破解。 Ncrack还可以针对特殊情况进行广泛的微调,尽管默认参数的通用性足以覆盖几乎所有情况。 它建立在模块化架构上,可以轻松扩展以支持其他协议…...
第二章:进程管理(处理机/CPU管理)
文章目录 2.1 进程与线程1.进程(1)进程的概念、进程的组成、进程的组织(2)进程控制块PCB(3)进程的状态与转换:五状态模型(4)进程控制(5)进程间的通信①共享存储②消息传递③管道通信(6)父进程与子进程(7)进程的内存空间2.线程 Thread(1)线程的概念(2)线程的实现方式:用户级线…...

MySQL中锁的简介——表级锁-元数据锁、意向锁
1.元数据锁 查看元数据锁 select object_type,object_scheme,object_name,lock_type,lock_duration from perfomance_scheme.metadata_locks;2.意向锁 线程A开启事务后在执行update更新语句时候,会给数据加上行锁,加上行锁以后,会对整张表加…...
React几种避免子组件无效刷新的方案
您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~ 前言 一个很常见的场景,React中父组件和子组件在一起,子组件不依赖于父组件任何数据,但是会一起发生变化。 在探究原…...

分享亿款好用的PDF编辑工具
所周知,PDF文件是不能够像word/excel/ppt等文件一样,可以被随意编辑的,PDF文件往往只能够被查看,我们无法对它进行编辑,或者对上面的文字进行复制,也不能任意删除上面的页面。但是很多时候,我们…...

AI生成式视频技术来临:Runway Gen-2文本生成视频
Runway Gen-2的官方网站提供了一种文本生成视频的工具。以下是对该工具的介绍: 文本生成视频:Runway Gen-2是一个创新的在线工具,可以将文本转化为视频。用户只需输入文本描述或句子,Runway Gen-2就能自动生成相应的视频内容。这…...
react钩子函数
React组件的生命周期包括多个阶段和方法,用于在组件不同的生命周期时执行特定的操作。以下是React类组件中常见的生命周期方法: 挂载阶段(Mounting Phase): constructor:组件实例化时调用,用于初…...

RISC-V公测平台发布 · 如何在SG2042上玩转k3s
前言 Kubernetes是一个开源的容器管理平台,通过Kubernetes的跨集群管理功能,用户可以方便地进行应用程序的复制、迁移和跨云平台的部署。 而k3s作为Kubernetes的轻量级发行版,相比传统的Kubernetes具有更小的二进制文件大小和更低的资源消耗…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...