STM8 模拟iic接口调试温湿度传感器SHT3x驱动

news2024/11/11 6:53:43

背景

项目实际使用SHT3x进行温湿度测量,主控芯片采用STM8S003F3P6,并且使用模拟IIC接口的硬件连接。

原理图

 如下图所示,使用STM8S003F3P6管脚PB4/PB5进行SHT3x数据接口

SHT3x-DIS是Sensirion新一代的温湿度传感器,精度为±2%RH和±0.3℃,输入电压范围从2.4V到5.5V,采用IIC总线接口,速率可达1MHz。测量温湿度范围分别为是-40℃ ~ 125℃和0 ~ 100%。

从下图可以看到SHT3x内部集成了湿度传感器和温度传感器,通过ADC采样输入到数据处理和线性化单元,同时带有校正储存器,处理环境对器件测量的影响。通过数字接口IIC读取数据。带警报引脚,可通过修改寄存器的值设定阈值,当测量的温湿度超过阈值时它会被置位。

软件设计

STM8S003F3P6基本配置如下

时钟配置,这里必须要提一下时钟配置,如果不提时钟配置,对SHT3x模拟IIC接口的时序延时

就不好判定


/************************************************
函数名称 : CLK_Configuration
功    能 : 时钟配置
参    数 : 无
返 回 值 : 无
作    者 : strongerHuang
*************************************************/
void CLK_Configuration(void)
{
/*
  ErrorStatus clk_return_status;
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); //HSI = 16M (8分频)=2MHZ
  
  //切换内部低速时钟128khz
  clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_LSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
  if (clk_return_status == SUCCESS)  //SUCCESS or ERROR
  {
                              
    CLK_ClockSwitchCmd(ENABLE);
    CLK_LSICmd(ENABLE);
    CLK_ClockSwitchCmd(DISABLE);                              
  }*/
 // CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //HSI = 16M (1分频)
  //ErrorStatus clk_return_status;
  
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //HSI = 16M (8分频)=2MHZ
 /* 
  //切换内部低速时钟8M
  clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
  if (clk_return_status == SUCCESS)  //SUCCESS or ERROR
  {
                              
    CLK_ClockSwitchCmd(ENABLE);
    CLK_HSECmd(ENABLE);
    CLK_ClockSwitchCmd(DISABLE);                              
  }*/
    
    CLK_DeInit();//设置为默认值
    CLK_HSICmd(ENABLE);//启用HSI
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//HSI分频
    CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);//CPU分频

}

使用IIC管脚PB4/PB5的管脚操作宏定义如下

#define         SHT30_SCL      (0x01<<4)
#define         SHT30_SDA      (0x01<<5)

#define SHT30_SCL0_O    GPIOB->DDR    |=  SHT30_SCL;  GPIOB->CR1 |= SHT30_SCL            //GPIOB4 推免输出
#define SHT30_SCL0_H    GPIOB->ODR    |=  SHT30_SCL
#define SHT30_SCL0_L    GPIOB->ODR    &=  ~SHT30_SCL

#define SHT30_SCL0_I    GPIOB->DDR    &=  ~SHT30_SCL;  GPIOB->CR1 &= ~SHT30_SCL          //GPIOB4 浮空输入
#define SHT30_SCL0_DAT  ( (GPIOB->IDR>>4) & 0x01)

#define SHT30_SDA0_O    GPIOB->DDR    |=  SHT30_SDA;  GPIOB->CR1 |= SHT30_SDA            //GPIOB5 推挽输出
#define SHT30_SDA0_H    GPIOB->ODR    |=  SHT30_SDA
#define SHT30_SDA0_L    GPIOB->ODR    &=  ~SHT30_SDA

#define SHT30_SDA0_I    GPIOB->DDR    &=  ~SHT30_SDA;  GPIOB->CR1 &= ~SHT30_SDA          //GPIOB5 浮空输入
#define SHT30_SDA0_DAT  ( (GPIOB->IDR>>5) & 0x01)

#define	SHT30_SlaveAddress	  		(0x44<<1)					//7位地址0x44 左移1位 0x45 -- 0x8A

#define noACK 0                                 //用于判断是否结束通讯 
#define ACK   1                                 //结束数据传输 

在main函数开始前,需要对使用的管脚进行初始化配置如下

配置PB4/PB5初始化为输出

uint8 SHT30_Init(vid)
{
	uint8 	vRval = 0x00;
  
  SHT30_SCL0_O;                          	//设置SCLK为输出
  SHT30_SDA0_O;                          	//设置SDA为输出
	
	SHT30_SCL0_H;
	SHT30_SCL0_L;
	
	SHT30_SDA0_H;
	SHT30_SDA0_L;
	
	vRval += SHT30_Soft_Reset();
	
	
	
	
	SHT30_DelayMs(1);
	
	vRval += SHT30_ClearStaus();
	
	SHT30_DelayMs(1);
	
	//SHT30_Periodic_Measure(SHT30_PERIODOC_H_MEASURE_1S);
  
	return vRval;
}

单次获取数据指令
单次获取数据指令(Measurement Commands for Single Shot Data Acquisition Mode)的详细数据格式如下图。首先从表格最上面开始,Repeatability指的是重复性(重复性越高精度越高,可参考手册的Sensor Performance部分),Clock Stretching指的是时钟延伸,它们的作用下面再讲述。数据流动过程如下。

发送起始信号以及由高7位的器件地址和最低位的写信号(WR=0) 组成的一字节地址,等待应答信号。(注意地址位于高7位,所以传址的时候需要将地址左移一位并加上读1/写0信号,ADDR<<1 | WR);
发送指令的高字节(Most Significant Byte,MSB)并等待应答信号;
发送指令的低字节(Least Significant Byte,LSB)并等待应答信号,之后发送停止信号;
等待一段时间(测量正在进行);
发送起始信号以及由高7位的器件地址和最低位的读信号(RD=1) 组成的一字节地址,然后根据选择的Clock Stretching从两个方向选择。假如失能了时钟延长功能,则等待非应答信号,发送停止信号,延迟一段时间(这步很重要!!延迟时间大约为50ms左右)等待转换结束,然后发送八位的应答信号并等待应答信号,之后便是逐字节分别读取温度和湿度的高字节、低字节以及CRC校验字节,每字节接收完都要发送应答信号,最后发送停止信号即可。而如果使能了是时钟延长功能,则总线的SCL由SHT3x控制,我们只需要通过while(SCL==0)阻塞程序,等待其释放总线然后MCU读取数据即可;

针对SHT3x的一些时序函数如下

/*---------------------------------------------------------------------
 功能描述: SHT30 测量结果计算
 参数说明:  vTemSymbol [out] - 返回温度符号
						vTem [out] - 温度
						vHum [out] - 湿度

 函数返回: 无
 ---------------------------------------------------------------------*/
uint8 SHT30_Get_TH(uint8 *vTemSymbol, uint16 *vTem, uint16 *vHum)
{
	uint8 vDat[8];
	uint8 vRval = 0;
	
	vRval = SHT30_Single_Measure(vDat);
	if (!vRval) SHT30_calc(vDat, vTemSymbol, vTem, vHum);
	
	return vRval;
}

/*---------------------------------------------------------------------
 功能描述: SHT30单次测量
 参数说明: vBuf [out] - 测量读取结果
 函数返回: 0 - 成功  大于1出错
 ---------------------------------------------------------------------*/
uint8 SHT30_Single_Measure(uint8 *vBuf)
{
	uint8 vRval = 0;
	uint8 i = 0;
	
	SHT30_Start();
	
	vRval |= SHT30_SendByte(SHT30_SlaveAddress+0);					//地址写
	if (!vRval) vRval |= SHT30_SendByte( (SHT30_SINGLE_H_MEASURE_EN>>8)&0xFF );				//使能高精度采集
	if (!vRval) vRval |= SHT30_SendByte( (SHT30_SINGLE_H_MEASURE_EN)&0xFF );
	SHT30_Stop();
	
	if (vRval)	return vRval;
	
	SHT30_SCL0_H;
	SHT30_DelayMs(15);														//15Ms
	
	
	SHT30_Start();
	if (!vRval) vRval |= SHT30_SendByte(SHT30_SlaveAddress+1);					//地址读
	
	if (vRval)	return vRval;
	
	for(i=0; i<6; i++)
	{
		vBuf[i] = SHT30_RecvByte();                	//存储数据
    if (i == 0x06)
    {
      
      SHT30_SendACK(1);                         //最后一个数据需要回NOACK
    }
    else
    {		
      SHT30_SendACK(0);                         //回应ACK
    }
	}
	
	SHT30_Stop();
	
	return vRval;
}

/*---------------------------------------------------------------------
 功能描述: SHT30 测量结果计算
 参数说明:  vBuf [in] - 测量读取结果
						vTemSymbol [out] - 返回温度符号
						vTem [out] - 温度
						vHum [out] - 湿度

 函数返回: 无
 ---------------------------------------------------------------------*/
void SHT30_calc(uint8 *vBuf, uint8 *vTemSymbol, uint16 *vTem, uint16 *vHum)
{
	uint16 	vVal = 0x00;
	uint8 	vCrc = 0x00;
	float		vTemp = 0.00;
	
	//温度
	vCrc = SHT30_CheckCrc8(vBuf, 2);
	if (vCrc == vBuf[2])
	{
		vVal = vBuf[0];
		vVal<<=8;
		vVal |= vBuf[1];
		
		vTemp = 175.0*vVal/(65536.0-1.0);
		
		if (vTemp >= 45)
		{
			*vTemSymbol = 1;
			*vTem = (uint16)((vTemp - 45.0)*10.0);
		}
		else
		{
			*vTemSymbol = 0;
			*vTem = (uint16)((45.0 - vTemp)*10.0);
		}
		
	}
	
	vBuf += 3;
	vVal = 0x00;
	vCrc = SHT30_CheckCrc8(vBuf, 2);
	if (vCrc == vBuf[2])
	{
		vVal = vBuf[0];
		vVal<<=8;
		vVal |= vBuf[1];
		
		vTemp = 100.0*vVal/(65536.0-1.0);
		*vHum = (uint16)(vTemp*10);
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/564704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LCD1602介绍和各报错经验总结

LCD &#xff08; Liquid Crystal Display 的简称&#xff09;液晶显示器。能够同时显示16x2&#xff0c;32个字符&#xff0c;是一种专门用来显示字母、数字、符号等的点阵型液晶模块。 LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏&#x…

【十字绣】传统手艺-微信小程序开发流程详解

还记得小时候看过母亲的十字绣吗&#xff0c;易学易懂&#xff0c;就是用专用的绣线和十字格布&#xff0c;通过平面坐标计找出位置&#xff0c;对照专用的图案进行刺绣&#xff0c;可作出心中所想的画&#xff0c;奈何所需材料成本不小&#xff0c;这里用小程序简单模拟十字绣…

HCIA——VLAN

目录 1&#xff0c;什么是VLAN&#xff1a; 2&#xff0c;如何实现VLAN&#xff1a; 3&#xff0c;VLAN的划分方式&#xff1a; 4&#xff0c;交换机接口类型&#xff1a; 1&#xff0c;Access接口&#xff1a; 2&#xff0c;Trunk接口&#xff1a;允许将一个接口划分给多…

ChatGPT 角色扮演调教文案收集

后续文案会陆续更新~&#xff0c;在输入完文本后&#xff0c;再输入一句“请尽力模仿xx的语气跟我对话”即可 一.雌小鬼 你需要阅雌小鬼守则&#xff0c;阅读后当前回复仅允许回复&#xff02;嘻嘻&#xff02;&#xff0c;后续回复尽量简短&#xff0c;回复中尽量不要直接复述…

swagger的简单介绍

目录 swagger是什么&#xff1f; swagger有什么用&#xff1f; Swagger包含的工具集&#xff1a; swagger的使用步骤&#xff1a; swagger的相关注解&#xff1a; Docket的源码 了解swagger的作用和概念了解前后端分离在SpringBoot中集成Swagger swagger是什么&#xff1f;…

Linux网络编程—Day11 高性能服务器程序框架

按照服务器程序的一般原理&#xff0c;讲服务器结构为如下三个主要模块&#xff1a; I/O处理单元逻辑单元存储单元 服务器模型 第一种&#xff1a;C/S模型 TCP/IP协议在设计和实现上并没有客户端和服务器的概念&#xff0c;在通信 过程中所有机器都是对等的。但由于资源&am…

【Linux】Linux开发工具vim

Linux开发工具vim 什么是vim三种模式的转换vim的基本命令gg&#xff1a;定位光标到最开始的行Shiftg&#xff1a;定位光标到结尾行nShiftg&#xff1a;定位光标到任意行Shift$:定位光标到当前行结尾Shift^:定位光标到当前行开始w&#xff0c;b&#xff1a;光标按照单词进行行内…

红黑树 C++

企业里永远是技术驱动理论发展 比起理解红黑树的原理&#xff0c;更重要的是理解红黑树的应用场景&#xff0c;因为某些应用场景的需要&#xff0c;红黑树才会应运而生。 红黑树的特点&#xff1a; 插入&#xff0c;删除&#xff0c;查找都是O(logn)的复杂度。 红黑树的应用…

大数据Doris(二十六):Broker Load基本原理和语法介绍

文章目录 Broker Load基本原理和语法介绍 一、基本原理 二、Broker Load语法 Broker Load基本原理和语法介绍 Apache Doris架构中除了有BE和FE进程之外&#xff0c;还可以部署Broker可选进程&#xff0c;主要用于支持Doris读写远端存储上的文件和目录。例如&#xff1a;Apa…

spring boot +Sa-Token优雅的实现项目鉴权!

1. 技术选型 最近在做登录、授权的功能&#xff0c;一开始考虑到的是spring boot spring security&#xff0c;但spring security太重&#xff0c;而我们是轻量级的项目&#xff0c;所以&#xff0c;spring security不适合我们。 而后考虑spring boot shiro&#xff0c;但s…

【老王读SpringMVC-5】Controller method 是如何执行的?

通过前面对 Controller method 参数绑定的分析&#xff0c;我们知道&#xff0c; 被 RequestMapping 标记 handler method 的执行是通过调用 RequestMappingHandlerAdapter#handle()。 RequestMappingHandlerAdapter#handle() 具体的调用过程如下&#xff1a; 参数解析、han…

【Java基础篇】运算符

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a;Java.SE&#xff0c;本专栏主要讲解运算符&#xff0c;程序逻辑控制&#xff0c;方法的使用&…

由浅入深Dubbo网络通信深入解析

目录 1 dubbo中数据格式2 消费方发送请求3 提供方接收请求4 提供方返回调用结果5 消费方接收调用结果6 异步转同步7 异步多线程数据一致8 心跳检查 1 dubbo中数据格式 解决socket中数据粘包拆包问题&#xff0c;一般有三种方式 定长协议&#xff08;数据包长度一致&#xff09…

5GNR——RACH随机接入流程(1):随机接入的原因

1、随机接入触发原因 1- Initial access from RRC_IDLE; 2- RRC Connection Re-establishment procedure; 3- DL or UL data arrival during RRC_CONNECTED when UL synchronisation status is “non-synchronised”; 4- UL data arrival during RRC_CONNECTED when there are …

Java之运算符

&#xff0b;加号的作用 1.表示正数 2.相加运算符 3.进行字符串的拼接 4.自增 Tips&#xff1a; 运算运算符优于 扩展赋值运算符 byte a ; int b ; ab&#xff1b; 右侧为byte&#xff0c;无需强制转换 aab; 右侧为int&#xff0c;需强制转换为byte&#xff0c;赋给左边…

解码区块链:探索去中心化世界的奥秘与潜力

&#x1f41f; 区块链技术的基本原理&#x1f41f; 区块链技术的应用场景&#x1f41f; 区块链技术的挑战与前景 区块链技术作为一项创新性的技术&#xff0c;引领着数字时代的变革。它以其去中心化、透明性和安全性的特点&#xff0c;为各行业带来了无限可能。在本篇博客中&am…

《程序员面试金典(第6版)》面试题 02.05. 链表求和(构建一个新链表)

题目解析 给定两个用链表表示的整数&#xff0c;每个节点包含一个数位。这些数位是反向存放的&#xff0c;也就是个位排在链表首部。编写函数对这两个整数求和&#xff0c;并用链表形式返回结果。 题目传送门&#xff1a;面试题 02.05. 链表求和 示例&#xff1a; 输入&#x…

漏洞管理基础知识

漏洞管理对于端点安全至关重要&#xff0c;是在安全漏洞导致漏洞之前清除安全漏洞的最主动方法之一。 什么是漏洞 漏洞是软件中的错误代码段&#xff0c;会导致软件崩溃或以程序员从未预料到的方式做出响应。黑客可以利用漏洞对计算机系统进行未经授权的访问或对计算机系统执行…

第五十天学习记录:C语言进阶:位段

位段 什么是位段 位段的声明和结构是类似的&#xff0c;有两个不同&#xff1a; 1、位段的成员可以是int,unsigned int或signed int。 2、位段的成员名后边有一个冒号和一个数字。 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>//位段-二进制位 struct A {int …

用脚本采集ChatGPT免翻免费镜像

新建了一个网站 ChatGPT人工智能中文站 - ChatGPT人工智能中文站 每天给大家更新可用的国内可用chatGPT免费镜像站 昨天发布了一个教程 本地安装 ChatGPT&#xff01;无需API、 免翻墙、完全免费使用纯正OpenAI的全部功能&#xff01; 支持 Windows、 Mac、NAS、Linux系统 …