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具有更小的二进制文件大小和更低的资源消耗…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...