文章目录

  • 前言
  • SHT30简介
    • 概述
    • 通信协议
  • 驱动文件
    • SHT30Driver.h
    • SHT30Recver.c
    • SHT30Cmder.c
    • 依赖
  • 使用示例
  • 更新历史

前言

干活中用到了SHT30,其实是对应的转串口板子,写了相应的驱动程序,放出来。

好像SHT20和30几乎是一样的,所以不用纠结这个。

这个模块本身的协议比较简单,所以模块的驱动也很小巧。

驱动被设计为拥有指令器和接收机两个部分,完全被动方式运行,与具体的平台解耦。

SHT30简介

概述

SHT20是由瑞士推出的数字温湿度传感器,基于领先世界的CMOSens数字传感技术,具有极高的可靠性和卓越的长期稳定性。全量程标定,两线数字接口,可与单片机直接相连,大大缩短研发时间、简化外围电路并降低费用。此外,体积微小、响应迅速、低能耗、可浸没、抗干扰能力强、温湿一体,兼有露点测量,性价比高,使该产品能够适于多种场合的应用。

通信协议

(1) 串口通信参数

电平:TTL
波特率:115200
停止位:1
校验位:0

(2)输出格式

输出字符串格式: Temp = XX.XXX Hum = XX.XXX\r\n

(3)控制指令:下面指令需要发送两次,第一次使模块由工作模式进入到配置模式,第二次发送才是设置模块。
设置回传速度:

设置报警值(这个驱动没有实现):

驱动文件

SHT30Driver.h

/*
*******************************************************************************************
*
*                                    SHT30 DRIVER MODULE
*                                       SHT30驱动模块
*
* File : SHT30Driver.h
* By   : Lin Shijun(https://blog.csdn.net/lin_strong)
* Date : 2020/06/17
* version: V1.1
* History: 2020/04/29 V1.0 the prototype
*          2020/06/17 V1.1 find that SHT30's data  is  "XXXX Hum = XXXX"
*                           but not "XXXX Humi = XXXX" in SHT20, so fix it.
* Note   : The SHT30 driver is divided into two part, i.e. cmder and recver. The cmder is for
*          sending the SHT30 command. The recver is for resolving data from the SHT30.
********************************************************************************************
*/#ifndef   SHT30DRIVER_H
#define   SHT30DRIVER_H/*
******************************************************************************************
*                                    INCLUDE
******************************************************************************************
*/#include <stdint.h>/*
******************************************************************************************
*                                    DEBUG CONFIGURATION
******************************************************************************************
*/// to enable debug messages in this module
// #define SHT30_DEBUG/*
******************************************************************************************
*                                       TYPE DEFINE
******************************************************************************************
*/typedef struct SHT30STRUCT_DATA{float temp;   // °Cfloat humi;   // percent
} SHT30Data;typedef void (* SHT30FUNC_DATA)(SHT30Data data);typedef enum {SHT30SR_10Hz ,SHT30SR_5Hz  ,SHT30SR_2Hz  ,SHT30SR_1Hz  ,SHT30SR_0d5Hz,  // 0.5HzSHT30SR_0d2Hz,  // 0.2HzSHT30SR_0d1Hz,  // 0.1Hz
}SHT30SampleRate;
/*
************************************************************************************
*                                    INTERFACES
************************************************************************************
*/void SHT30Cmder_Init(void (* outChannel)(uint8_t *buf, uint16_t len));
void SHT30Cmder_Destroy(void);
void SHT30Cmder_setSampleRate(SHT30SampleRate value);void SHT30Recver_Init(SHT30FUNC_DATA onRecvData);
// Call it to modify the call-back function.
void SHT30Recver_RegisterCallback(SHT30FUNC_DATA onRecvData);
void SHT30Recver_CleanupBuffer(void);
// Feed the receiver every byte received so that receiver can notify user
// the resolved data for each frame.
void SHT30Recver_Feed(uint8_t nextByte);
void SHT30Recver_Destroy(void);#endif  // of SHT30DRIVER_H

SHT30Recver.c

/*
*******************************************************************************************
*
*                                   SHT30 RECEIVER MODULE
*                                   SHT30驱动模块 - 接收机
*
* File : SHT30Recver.c
* By   : Lin Shijun(https://blog.csdn.net/lin_strong)
* Date : 2020/06/17
* version: V1.1
* History: 2020/06/17
* Note   :
********************************************************************************************
*//*
*********************************************************************************************
*                                       INCLUDES
*********************************************************************************************
*/#include <string.h>
#include <ctype.h>
#include "SHT30Driver.h"
#include "RxMac.h"#ifndef SHT30_DEBUG
#undef _DEBUG
#endif#include "DebugMsg.h"/*
*********************************************************************************************
*                                       LOCAL FUNCTION
*********************************************************************************************
*/#define ARRAYSIZE(arr)  (sizeof(arr)/ sizeof(arr[0]))
static void _onFlushed(RxMac sender,RxMacPtr buf,uint16_t len,RxState state,RxFlag HorU,RxFlag Ender);/*
*********************************************************************************************
*                                       LOCAL VARIABLE
*********************************************************************************************
*/static const char * _str_SHT30Recver = "SHT30Recver";static SHT30FUNC_DATA _onRecvData;
static const uint8_t _flag_header[] = {(uint8_t)'T', (uint8_t)'e', (uint8_t)'m', (uint8_t)'p', (uint8_t)' ', (uint8_t)'=', (uint8_t)' '};
static const uint8_t _flag_ender[] = {(uint8_t)'\r', (uint8_t)'\n'};
static const RXFLAG_STRUCT _flags[] = {{_flag_header, sizeof(_flag_header), RXFLAG_OPTION_STRONG_HEADER},{_flag_ender , sizeof(_flag_ender) , RXFLAG_OPTION_STRONG_ENDER }
};
static RxMac _mac;
static uint8_t _macBuf[36];/*
*********************************************************************************************
*                                 INTERFACE IMPLEMENTATION
*********************************************************************************************
*/void SHT30Recver_Init(SHT30FUNC_DATA onRecvData){_onRecvData = onRecvData;_mac = RxMac_Create(_flags, ARRAYSIZE(_flags), _macBuf, sizeof(_macBuf) - 1,NULL, NULL, _onFlushed);if(_mac == NULL)for(;;);
}void SHT30Recver_Destroy(){_onRecvData = NULL;RxMac_Destroy(_mac);
}void SHT30Recver_RegisterCallback(SHT30FUNC_DATA onRecvData){_onRecvData = onRecvData;
}void SHT30Recver_CleanupBuffer(void){RxMac_ResetState(_mac);
}void SHT30Recver_Feed(uint8_t nextByte){RxMac_FeedData(_mac, nextByte);
}/*
*********************************************************************************************
*                               LOCAL FUNCTION IMPLEMENTATION
*********************************************************************************************
*/
static int _FloatFormatRight(const char *beg, const char *end){const char *p;if(end - beg <= 0)return 0;for(p = beg; end - p > 0; p++)if(!isdigit(*p) && *p != '-' && *p != '.')return 0;return 1;
}static void _onFlushed(RxMac sender,RxMacPtr buf,uint16_t len,RxState state,RxFlag HorU,RxFlag Ender){const char *p;SHT30Data data;if(_onRecvData == NULL || !state.headerFound || !state.enderFound)return;buf[len] = '\0';p = strstr((const char *)buf, "   Hum = ");if(p == NULL || !_FloatFormatRight((const char *)&buf[7], p) || !_FloatFormatRight((const char *)&p[9], (const char *)buf + len - 2)){_dbg_printf2("%s: got corrupt frame-%s", _str_SHT30Recver, (const char *)buf);return;}data.temp  = (float)atof((const char *)&buf[7]);data.humi  = (float)atof((const char *)&p[9]);_dbg_printf3("%s: got data-temp(%.3f),humi(%.3f)\r\n", _str_SHT30Recver, data.temp, data.humi);_onRecvData(data);
}

SHT30Cmder.c

/*
*******************************************************************************************
*
*                                    SHT30 COMMANDER MODULE
*                                    SHT30驱动模块 - 指令器
*
* File : SHT30Cmder.c
* By   : Lin Shijun(https://blog.csdn.net/lin_strong)
* Date : 2020/06/17
* version: V1.1
* History: 2020/06/17
* Note   : Only implement the set sample rate command for now.
********************************************************************************************
*//*
*********************************************************************************************
*                                       INCLUDES
*********************************************************************************************
*/#include <stdio.h>
#include "SHT30Driver.h"/*
*********************************************************************************************
*                                       LOCAL VARIABLE
*********************************************************************************************
*/
static void (* _out)(uint8_t *buf, uint16_t len) = NULL;/*
*********************************************************************************************
*                                 INTERFACE IMPLEMENTATION
*********************************************************************************************
*/void SHT30Cmder_Init(void (* outChannel)(uint8_t *buf, uint16_t len)){_out = outChannel;
}void SHT30Cmder_Destroy(){_out = NULL;
}void SHT30Cmder_setSampleRate(SHT30SampleRate value){uint8_t buf[] = {0xFF, 0xAA, 0x09, 0x00, 0x00};buf[3] = (uint8_t)value;if(_out != NULL)_out(buf, sizeof(buf));
}

依赖

接收器的实现依赖于我写的通用接收机:
通用接收状态机模块

至于DebugMsg.h则是我自己使用的调试信息的模块:

#ifndef _DEBUG_MSG_H
#define _DEBUG_MSG_H
#include <stdio.h>
#ifdef _DEBUG#define _dbg_printf0(format)                   ((void)printf(format))#define _dbg_printf1(format,p1)                ((void)printf(format,p1))#define _dbg_printf2(format,p1,p2)             ((void)printf(format,p1,p2))#define _dbg_printf3(format,p1,p2,p3)          ((void)printf(format,p1,p2,p3))#define _dbg_printf4(format,p1,p2,p3,p4)       ((void)printf(format,p1,p2,p3,p4))#define _dbg_printf5(format,p1,p2,p3,p4,p5)    ((void)printf(format,p1,p2,p3,p4,p5))#define _dbg_printf6(format,p1,p2,p3,p4,p5,p6) ((void)printf(format,p1,p2,p3,p4,p5,p6))#define _dbg_printf7(format,p1,p2,p3,p4,p5,p6,p7) \((void)printf(format,p1,p2,p3,p4,p5,p6,p7))#define _dbg_printf8(format,p1,p2,p3,p4,p5,p6,p7,p8) \((void)printf(format,p1,p2,p3,p4,p5,p6,p7,p8))#define _dbg_printf9(format,p1,p2,p3,p4,p5,p6,p7,p8,p9) \((void)printf(format,p1,p2,p3,p4,p5,p6,p7,p8,p9))
#else#define _dbg_printf0(format)#define _dbg_printf1(format,p1)#define _dbg_printf2(format,p1,p2)#define _dbg_printf3(format,p1,p2,p3)#define _dbg_printf4(format,p1,p2,p3,p4)#define _dbg_printf5(format,p1,p2,p3,p4,p5)#define _dbg_printf6(format,p1,p2,p3,p4,p5,p6)#define _dbg_printf7(format,p1,p2,p3,p4,p5,p6,p7)#define _dbg_printf8(format,p1,p2,p3,p4,p5,p6,p7,p8)#define _dbg_printf9(format,p1,p2,p3,p4,p5,p6,p7,p8,p9)
#endifint dummyprintf(const char *format, ...);#endif

这样在项目中同时宏定义 _DEBUGSHT30_DEBUG 时才会打印调试信息。不需要的话删除相关语句就好。

想要了解相关技巧的话详见:
C语言宏配置的各种奇淫技巧

使用示例

使用此模块基本分几步:

  1. 初始化模块
  2. 如需要发送指令则实现并注册信道给指令器;注册回调函数给接收器,这样接收器在发现完整的数据帧时就会通过回调函数进行通知。
  3. 不断接收数据,并喂(Feed)给接收器;如需要发指令,随时调用指令器的接口。

以下代码示例了在上电后不断读取数据并进行解析(假设使用标准输入输出上的串口和SHT30通信):


#include "SHT30Driver.h"
#include <stdio.h>
#include <stdint.h>
……
// 收到数据的回调函数
static void onDataResolved(SHT30Data data);
// 发送信道
static void sendChannel(uint8_t *buf, uint16_t len);void main(){uint8_t b;……SHT30Recver_Init(onDataResolved);SHT30Cmder_Init(sendChannel);// 如果需要调整采样率的话发送对应指令,注意要先发一次指令使进入配置模式的问题// SHT30Cmder_setSampleRate(SHT30SR_1Hz);for(;;){// 不断得到下一个字节并喂给接收机// 接收机会通过回调函数实时传递解析出来的值b = (uint8_t)getchar();SHT30Recver_Feed(b);}
}static void onDataResolved(SHT30Data data){// data中就是实时解析到的数据,具体怎么使用是你的事
}static void sendChannel(uint8_t *buf, uint16_t len){// 往标准输出输出这个字节while(len-- > 0)putchar((char)*buf++);
}

更新历史

2020/06/07 放出V1.0
2020/06/17 发现了SHT30和SHT20在数据输出格式上一个是Humi,一个是Hum,所以修正为了SHT30的Hum。如果是SHT20。则将Recver中的onFlush函数按如下修改即可。

static void _onFlushed(RxMac sender,RxMacPtr buf,uint16_t len,RxState state,RxFlag HorU,RxFlag Ender){const char *p;SHT30Data data;if(_onRecvData == NULL || !state.headerFound || !state.enderFound)return;buf[len] = '\0';p = strstr((const char *)buf, "   Humi = ");if(p == NULL || !_FloatFormatRight((const char *)&buf[7], p) || !_FloatFormatRight((const char *)&p[10], (const char *)buf + len - 2)){_dbg_printf2("%s: got corrupt frame-%s", _str_SHT30Recver, (const char *)buf);return;}data.temp  = (float)atof((const char *)&buf[7]);data.humi  = (float)atof((const char *)&p[10]);_dbg_printf3("%s: got data-temp(%.3f),humi(%.3f)\r\n", _str_SHT30Recver, data.temp, data.humi);_onRecvData(data);
}

[嵌入式开发模块]SHT30/20 温湿度传感器 驱动模块相关推荐

  1. 嵌入式开发在过去20年中是如何演变的

    嵌入式开发在过去20年中是如何演变的 How embedded development has evolved over the past two decades 与任何开发领域一样,嵌入式系统开发就 ...

  2. Arduino开发板使用DHT11温湿度传感器的方法

    在本篇文章中,我们将DHT11温湿度传感器与Arduino开发板和LCD显示屏连接,设计一种能够测量室温和环境湿度的设备.简单地说,我们将使用Arduino和DHT11传感器设计数字湿度和温度计,并将 ...

  3. c语言数组实现环形缓冲区,[嵌入式开发模块]环形缓冲区/循环队列 C语言实现

    忙着毕设,很久没有写文章了,终于答辩完了,得了个校优秀毕业设计.毕设做的是个智能接口模块,用一周时间入门了,MC9S12XEP100的开发,又用一周时间入门了uC/OS-II嵌入式操作系统,在做毕设的 ...

  4. [嵌入式开发模块]JY61姿态角度传感器 驱动模块

    文章目录 前言 JY61简介 概述 通信协议 驱动文件 JY61Driver.h JY61Recver.c JY61Cmder.c 依赖 使用示例 更新历史 前言 干活中用到了JY61姿态角度传感器, ...

  5. [嵌入式开发模块]GY25倾斜角度传感器 驱动模块

    文章目录 前言 GY25简介 概述 通信协议 驱动文件 GY25Driver.h GY25Recver.c GY25Cmder.c 依赖 使用示例 更新历史 前言 干活中用到了GY25传感器模块,写了 ...

  6. [嵌入式开发模块]AD转换芯片ADS8344驱动模块

    文章目录 芯片简介 代码 头文件 源文件 使用及示例代码 芯片简介 ADS8344是一个8通道16位模数转换器,使用SPI接口. 其可以使用单端或差分输入,单端模式时,每个CHX独立作为采样输入,测其 ...

  7. 嵌入式开发模块]AD转换芯片ADS8344驱动模块16位分辨率,程序实例

    文章目录 芯片简介 代码 头文件 源文件 使用及示例代码 芯片简介 ADS8344是一个8通道16位模数转换器,使用SPI接口. 其可以使用单端或差分输入,单端模式时,每个CHX独立作为采样输入,测其 ...

  8. MSP430 单片机 SHT30 SHT31 温湿度传感器 MSP430F5529 MSP430G2553 程序

    SHT30和SHT31程序是一样的 手册是一样的 寄存器是一样的 操作都是一样的. 唯一 不同点是:SHT31的湿度波动小,测量较准确. 推荐打开SHT3X的周期测量模式,然后一直循环读取寄存器即可, ...

  9. [嵌入式开发模块]通用接收状态机模块

    文章目录 前言 模块相关概念和逻辑 接收机状态 标志字符序列 flush 接收机类 过滤器 onGetHeader事件 接收机运行逻辑 边际条件 相关代码 接收机代码 RxMac.h RxMacPri ...

最新文章

  1. mybatis-plus对datetime返回去掉.0_华为AI认证-TensorFlow2.0编程基础
  2. C#_Math函数总结
  3. 查看linux4222端口,linux 内核 ALIGN 含义
  4. python3.6安装教程-Python 3.6.6安装教程(附安装包) | 我爱分享网
  5. UA MATH524 复变函数13 补充:留数计算的例题
  6. git cherry-pick简介
  7. 基于用例点来度量软件规模并管理进度 之结束语
  8. EasyUI表单验证,自定义插件验证,自定义js插件验证,远程验证,常见手机号,中英文,qq等验证规则验证
  9. 卷积神经网络——池化层学习——最大池化
  10. spark中使用categoricalFeaturesInfo来标记分类型变量
  11. oracle 10g安装需注意细节
  12. 网络管理与维护作业5
  13. 下载安装tomcat和jdk,配置运行环境,与Intellij idea 2017关联
  14. [Google Guava]学习--新集合类型BiMap
  15. idea svn回退版本_mac下使用svn通过终端回退版本到某个版本号 - 博客频道 - CSDN.NET...
  16. 吴伯凡-认知方法论-知行合一-建立神经元之间的高带宽连接
  17. Python 给图片上加文字
  18. World Locking Tools for Unity (一)指南部分
  19. 11.0、C语言数据结构——栈
  20. mysql加密函数password

热门文章

  1. 【web开发】利用User-Agent获取浏览器类型
  2. [linux-023]在thinkpad T480上安装ubuntu 20.04 LTS
  3. 输出菱形(C语言,萌新向)
  4. 通过RSRP和SINR判断LTE信号质量
  5. 学习VR技术要学哪些内容?VR全景如何制作?
  6. java面试题2019最新
  7. SpringBoot实现微信登录
  8. 超给力,一款程序员必备的 996 代码工作量分析工具
  9. cmd 批量命名,批量删除
  10. 「跑象科技」获得天使+融资,打造新一代实时数据基础平台