STM32物联网项目-SHT30温湿度采集(IIC通信)

这篇具有很好参考价值的文章主要介绍了STM32物联网项目-SHT30温湿度采集(IIC通信)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SHT30温湿度采集(IIC通信)

SHT30数字温湿度传感器

STM32物联网项目-SHT30温湿度采集(IIC通信)

SHT3x湿度传感器系列包括低成本版本SHT30、标准版本SHT31,以及高端版本SHT35。

SHT3x湿度传感器系列结合了多种功能和各种接口(I2C、模拟电压输出),应用友好,工作电压范围宽(2.15至5.5 V),适合各类应用。

SHT3x建立在全新和优化的CMOSens® 芯片之上,进一步提高了产品可靠性和精度规格。SHT3x提供了一系列新功能,如增强信号处理、两个独特和用户可选I2C地址、一个可编程温湿度极限的报警模式,以及高达1 MHz的通信速度。

DFN封装的占位面积为2.5 × 2.5 mm2,高度为0.9 mm。这有助于SHT3x集成到多种应用。此外,2.15至5.5 V的宽电源电压范围和多种可选接口可保证与不同集成要求的兼容性。总之,SHT3x湿度传感器系列融入了Sensirion作为行业领导者15年的经验和心血,是一款超高性价比的产品。

特点

完全校准,线性化,和温度补偿数字输出

宽电源电压范围,从2.4到5.5 V

IIC接口通信速度1 MHz和两个用户可选择的地址

典型精度2%RH(湿度)和0.3°C(温度)

非常快速启动和测量时间

小8针DFN包(封装)

32引脚既作输入又作输出

在51单片机中,引脚都叫通用输入输出引脚,是具有双向功能的,32单片机的引脚也可以

开漏输出框图

STM32物联网项目-SHT30温湿度采集(IIC通信)

CPU往位设置寄存器写入1,则高电平1来到输出控制电路这里,N-MOS管不会导通,此时IO端口的电平状态由外部的上拉或者下拉决定,可能为高电平也可能为低电平;同时IO端口的状态可以被读取,通过虚线的电路被CPU读取,此时读取的并不一定是CPU输出的高电平1,而是外部的状态

CPU如果往位设置寄存器写入0,则低电平0来到输出控制寄存器,N-MOS管导通,IO端口与VSS导通,而VSS是电路公共地端电压,一般接GND,所以IO端口就输出低电平0;同时CPU读取时端口状态就是自己输出的低电平0

所以IO引脚配置为开漏输出就既可以作输出又可以作输入了,并不需要再配置改变IO口的工作模式

SHT30通信引脚配置

因为SHT30是IIC通信的,SCL与SDA均配置为开漏输出,总线上均有上拉电阻。因此,SDA作为输出的同时,也可以作为输入使用。与51内核的准双向口一样,作为输入使用时,需要先输出高电平,关闭内部的NMOS管。

CubeMX配置

因为IIC通信的SCL引脚接到了PG11,SDA接到了PG12,所以需要配置这两个引脚为开漏输出

STM32物联网项目-SHT30温湿度采集(IIC通信)

PG11和PG12都配置为开漏输出,并输出高电平,因为是通信,输出速度可以选高速

其他配置如定时器6,数码管,串口,LED灯按照之前实验中配置方法就行,系统时钟72MHz

程序

IIC.c

STM32物联网项目-SHT30温湿度采集(IIC通信)

根据IIC通信时序图编写函数,本次使用软件模拟IIC通信的方式,对IIC通信加深理解

IIC通信介绍可以参考:http://t.csdn.cn/xvYI5

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/
#define SET_SCL HAL_GPIO_WritePin(SCL_GPIO_Port,SCL_Pin,GPIO_PIN_SET)
#define CLR_SCL HAL_GPIO_WritePin(SCL_GPIO_Port,SCL_Pin,GPIO_PIN_RESET)

#define SET_SDA HAL_GPIO_WritePin(SDA_GPIO_Port,SDA_Pin,GPIO_PIN_SET)
#define CLR_SDA HAL_GPIO_WritePin(SDA_GPIO_Port,SDA_Pin,GPIO_PIN_RESET)

#define READ_SDA HAL_GPIO_ReadPin(SDA_GPIO_Port,SDA_Pin)

/* Private function prototypes------------------------------------------------*/
static void IIC_Init(void);
static void IIC_Start(void);
static void IIC_Stop(void);
static void Write_Byte(uint8_t );
static uint8_t Recive_Byte(void);
static void SendACK(ACK_Value_t );
static ACK_Value_t ReciveACK(void);
static void IIC_Delay_us(uint8_t );
/* Private variables----------------------------------------------------------*/

/* Public variables-----------------------------------------------------------*/
IIC_Soft_t IIC_Soft = 
{
    IIC_Init,
    IIC_Start,
    IIC_Stop,
    Write_Byte,
    Recive_Byte,
    SendACK,
    ReciveACK
};

/*
* @name   IIC_Init
* @brief  IIC初始化
* @param  None
* @retval None
*/
static void IIC_Init()
{
    SET_SCL;
    SET_SDA;
}

/*
* @name   IIC_Start
* @brief  起始信号
* @param  None
* @retval None
*/
static void IIC_Start()
{
    //SCL为高电平时,SDA的下降沿为IIC的起始信号
    SET_SCL;
    SET_SDA;
    IIC_Delay_us(1);
    CLR_SDA;
    IIC_Delay_us(10);
    CLR_SCL;
    IIC_Delay_us(1);
}

/*
* @name   IIC_Stop
* @brief  停止信号
* @param  None
* @retval None
*/
static void IIC_Stop()
{  
    //SCL为高电平时,SDA的上升沿为IIC的停止信号
    CLR_SDA;
    SET_SCL;
    IIC_Delay_us(10);
    SET_SDA;
}

/*
* @name   Write_Byte
* @brief  主机发送一个字节
* @param  WR_Byte:要发送的数据
* @retval None
*/
static void Write_Byte(uint8_t WR_Byte)
{
    uint8_t i;
    //传输一个字节
    /*SCL为低电平时,SDA准备数据,接着SCL为高电平,读取SDA数据
	数据按8位传输,高位在前,利用for循环逐个接收*/
    for(i=0;i<8;i++)
    {
        CLR_SCL;            //拉低SCL
        IIC_Delay_us(1);
        if((WR_Byte&BIT7) == BIT7)	//如果一个字节最高位为1
        {
            SET_SDA;        //往SDA上放1
        }
        else
        {
            CLR_SDA;        //否则往SDA上放0
        }
        IIC_Delay_us(1);
        SET_SCL;            //拉高SCL,从机读取数据
        IIC_Delay_us(10);
        WR_Byte <<= 1;      //左移一位,发送下一位
    }
}

/*
* @name   Recive_Byte
* @brief  主机接收一个字节
* @param  None
* @retval 接收到的数据
*/
static uint8_t Recive_Byte()
{
    uint8_t i,Re_Byte = 0x00;

    //释放SDA,将控制权交给从机,即SDA = 1
    SET_SDA;
    //接收一个字节
    for(i=0;i<8;i++)
    {
        CLR_SCL;    //拉低SCL,从机SDA准备数据
        IIC_Delay_us(10);

        SET_SCL;    //拉高SCL,读取数据
        IIC_Delay_us(10);
        if(READ_SDA == GPIO_PIN_SET)
        {
            Re_Byte|=(BIT7>>i);
        } 
    }
    return Re_Byte;
}

/*
* @name   SendACK
* @brief  主机发送应答
* @param  ACK_Value:ACK:应答,NACK:非应答
* @retval None
*/
static void SendACK(ACK_Value_t ACK_Value)
{
    CLR_SCL;        //拉低SCL,主机准备发送应答信息
    IIC_Delay_us(1);
    //发送应答信息
    if(ACK_Value == ACK)
    {
        CLR_SDA;    //0表示应答       
    }
    else
    {
        SET_SDA;    //1表示非应答
    }
    IIC_Delay_us(1);
    SET_SCL;        //拉高SCL,主机发送应答
    IIC_Delay_us(1);
    //释放SDA数据线
	//SCL先清零,再释放SDA,防止连续传输数据时,从机错将SDA释放信号当成NACk信号
    CLR_SCL;        //拉低SCL
    SET_SDA;        //因为主机发送应答后,从机可能会继续发送数据,所以控制权要给到从机
    IIC_Delay_us(1);
}

/*
* @name   ReciveACK
* @brief  主机接收应答,判断从机是否应答
* @param  None
* @retval 从机的应答
*/
static ACK_Value_t ReciveACK()
{
    uint8_t RecAck;
    CLR_SCL;            //拉低SCL
    SET_SDA;            //主机释放SDA,将控制权交给从机,即SDA = 1
    IIC_Delay_us(1);
    SET_SCL;            //拉高SCL,读取SDA的值
    IIC_Delay_us(10);
    RecAck = READ_SDA;  //读取SDA的值,0表示应答,1表示非应答
    CLR_SCL;
    IIC_Delay_us(1);
    return (ACK_Value_t)RecAck;
}

/*
* @name   IIC_Delay_us
* @brief  IIC延时函数——微秒级,
* @param  us:要延时的时间
* @retval None
*/
static void IIC_Delay_us(uint8_t us)
{
    uint16_t i;
	//通过示波器测量进行校准
    while(us--)
    {
        for(i=0;i<7;i++);
    }
}
/********************************************************
  End Of File
********************************************************/

SHT30.c

根据SHT30的数据手册来编写通信函数

4.5定期数据采集模式的测量命令

在这种模式下,一个发出的测量命令会产生一个数据对流。每个数据对由一个16位温度值和一个16位湿度值(按此顺序)组成。在周期模式下,可以选择不同的测量命令。对应的16位命令如表9所示。它们在可重复性(低、中、高)和数据采集频率(每秒0.5、1、2、4和10次测量值,mps)方面存在差异。在此模式下不能选择时钟拉伸。数据采集频率和可重复性设置会影响传感器的测量持续时间和电流消耗。

STM32物联网项目-SHT30温湿度采集(IIC通信)

根据表格下方的通信时序,主机发送起始信号,然后发送从机地址加写指令命令,等待从机应答,再发送命令的高位(MSB),等待从机应答,再发送命令的低位(LSB)

调用IIC的函数,根据通信时序,完成设置周期测量模式

//设置周期测量模式
IIC_Soft.IIC_Start();
IIC_Soft.Write_Byte(SHT30_ADDR&WRITE_CMD);
IIC_Soft.ReciveACK();
IIC_Soft.Write_Byte(0x27);  //MSB,设置Repeatability为High,mps为10的测量模式
IIC_Soft.ReciveACK();
IIC_Soft.Write_Byte(0x37);	//LSB
IIC_Soft.ReciveACK();

4.6周期模式下测量结果的读数

读数可以通过表10所示的命令启动。如果没有测量数据,I2C读取头用NACK而不是ACK(表10中的位9)响应,通信停止。

空白的数据块是由32发送,黑色的数据块是由SHT30发送

STM32物联网项目-SHT30温湿度采集(IIC通信)

根据表10的通信时序,获取SHT30的温湿度数据,读数据的命令是0xE000,获取的是16位的温度值和16位的湿度值,温度和湿度后都有CRC-8校验

STM32物联网项目-SHT30温湿度采集(IIC通信)

从SHT30读出的16位温度和16位湿度还不是真正的温湿度值,而是要根据上面这个公式来计算得到正确的温湿度值,RH是湿度,T是温度

通信时序代码

在通过公式计算温湿度值时,因为216 - 1是65535,175/65535 = 0.002670328…,结果除不尽,但浮点型float的精度为6~7位有效数字,直接计算的话相当于把小数点后7位之后的数据省略掉了,会造成计算出来的温湿度精度有些损失,所以有了这样的方法:先让公式的数值都*100,这样的话计算出来的温湿度值也会 *100,但这样计算的小数位就会多两位,精度较为准确,在赋给最后结果变量前再 *0.01,将结果变回正常值即可

 	//读取数据
    Timer6.SHT30_Measure_Timeout = 0;
    do
    {
        //如果2秒内没有获取到数据,则break退出
        if(Timer6.SHT30_Measure_Timeout >= TIMER_2s)
        {
            LED.LED_Fun(LED2,LED_OFF);
            break;
        }
        IIC_Soft.IIC_Start();
        IIC_Soft.Write_Byte(SHT30_ADDR&WRITE_CMD);
        IIC_Soft.ReciveACK();
        //0xE000是向SHT30取数据的指令,主机发送该指令后开始读取SHT30的温湿度数据
        IIC_Soft.Write_Byte(0xE0);  
        IIC_Soft.ReciveACK();
        IIC_Soft.Write_Byte(0x00);
        IIC_Soft.ReciveACK();
        //重新发送起始信号,往SHT30发送地址加读取数据指令
        IIC_Soft.IIC_Start();
        IIC_Soft.Write_Byte(SHT30_ADDR|READ_CMD);
    /*判断是否收到从机应答,主机收到NACK时,继续循环发送取数据指令,主机收到ACK时,不满足
    条件,退出,往下执行*/
    } while (IIC_Soft.ReciveACK() == NACK); 
	//接收温湿度数据
    //判断是否是超时退出,如果不是,则有数据,进行接收;如果是则没有数据,不处理
    if(Timer6.SHT30_Measure_Timeout < TIMER_2s)
    {
        temp_array[0] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[1] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[2] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[3] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[4] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(ACK);
        temp_array[5] = IIC_Soft.Recive_Byte();IIC_Soft.SendACK(NACK);
        IIC_Soft.IIC_Stop();

        //计算温度
        if(CRC_8(temp_array,2) == temp_array[2])                //进行CRC-8校验
        {
            temp_uint = temp_array[0]*256+temp_array[1];        //取出16位的温度值
            temp_float = ((float)temp_uint)*0.267032-4500;    //根据手册公式计算,为了精度,计算数值先*100
            SHT30.fTemperature = temp_float*0.01;             //再除以100,得到正常温度值
        }

        //计算湿度
        if(CRC_8(&temp_array[3],2) == temp_array[5])            //进行CRC-8校验
        {
            temp_uint = temp_array[3]*256+temp_array[4];        //取出16位的湿度值
            temp_float = ((float)temp_uint)*0.152590;           //根据手册公式计算
            SHT30.ucHumidity = (uint8_t)(temp_float*0.01);      //除以100,得到正常湿度值
        }
        LED.LED_Fun(LED1,LED_OFF);	//转换完成LED1熄灭
    }
}

CRC-8检验函数

/*
* @name   CRC_8
* @brief  CRC-8校验
* @param  Crc_ptr -> 校验数据首地址
		LEN     -> 校验数据长度
* @retval CRC_Value -> 校验值      
*/
static uint8_t CRC_8(uint8_t *Crc_ptr,uint8_t LEN)
{
	uint8_t CRC_Value = 0xFF;
	uint8_t i = 0,j = 0;

	for(i=0;i<LEN;i++)
	{
		CRC_Value ^= *(Crc_ptr+i);
		for(j=0;j<8;j++)
		{
			if(CRC_Value & 0x80)
				CRC_Value = (CRC_Value << 1) ^ 0x31;
			else
				CRC_Value = (CRC_Value << 1);
		}
	}
	return CRC_Value;
}

System.c

系统运行函数中实现串口打印以及数码管显示温湿度值

/*
* @name   Run
* @brief  系统运行
* @param  None
* @retval None   
*/
static void Run()
{
  float   Temp_float = 0;
  uint16_t Temp_uint  = 0;
  //调用SHT30周期检测函数
  SHT30.Measure_Period_Mode();

  //串口打印温湿度
  printf("温度:%.1f度\r\n",SHT30.fTemperature);
  printf("湿度:%d%%RH\r\n\r\n",SHT30.ucHumidity);

  //判断温度正负
  if(SHT30.fTemperature < 0)
  {
    Temp_float = 0 - SHT30.fTemperature;
    Display.Disp_Other(Disp_NUM_4,0x40,Disp_DP_OFF);
  }
  else
  {
    Temp_float = SHT30.fTemperature;
    Display.Disp_Other(Disp_NUM_4,0x00,Disp_DP_OFF);
  }

  //显示温度
  Temp_uint = (uint16_t)(Temp_float*10); //将温度值乘以10,显示小数点后一位
  Display.Disp_Hex(Disp_NUM_3,Temp_uint/100,Disp_DP_OFF);   //显示十位
  Display.Disp_Hex(Disp_NUM_2,Temp_uint%100/10,Disp_DP_ON);  //显示个位,开启小数点
  Display.Disp_Hex(Disp_NUM_1,Temp_uint%10,Disp_DP_OFF);    //显示小数点后一位

  //显示湿度
  Display.Disp_Hex(Disp_NUM_6,SHT30.ucHumidity/10,Disp_DP_OFF);
  Display.Disp_Hex(Disp_NUM_5,SHT30.ucHumidity%10,Disp_DP_OFF);

  //延时
  HAL_Delay(500);
}

实验效果

串口打印

STM32物联网项目-SHT30温湿度采集(IIC通信)

数码管显示

STM32物联网项目-SHT30温湿度采集(IIC通信)文章来源地址https://www.toymoban.com/news/detail-420258.html

到了这里,关于STM32物联网项目-SHT30温湿度采集(IIC通信)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式 STM32 SHT31温湿度传感器

    目录 简介 1、原理图  2、时序说明  数据传输 起始信号  结束信号  3、SHT31读写数据  SHT31指令集 读数据  温湿度转换 4、温湿度转换应用  sht3x初始化 读取温湿度  什么是SHT31?  一主机多从机--通过寻址的方式--每个从机都有唯一的地址(器件地址0x44+引脚地址)1 + 读写位

    2024年02月01日
    浏览(30)
  • STM32之模拟IIC总线控制SHT20温湿度芯片

    一、IIC总线概述 1、IIC总线介绍 I2C (Inter-Integrated Circuit)总线产生于在80年代, 由PHILIPS公司开发的 两线式串行总线 ,用于连接微控制器及其外围设备, 最初为音频和视频设备开发。I2C总线两线制包括: 串行数据 SDA (Serial Data)、 串行时钟 SCL (Serial Clock)。时钟线必须由主

    2024年02月02日
    浏览(16)
  • STM32Cubemxhal库硬件IIC驱动SHT40温湿度传感器

    STM32cubemx配置硬件IIC如图所示  SHT40的驱动代码 注意:在读sht40的寄存器之后一定要加10几个ms的延时

    2024年02月12日
    浏览(12)
  • SHT30温湿度传感器应用笔记

            SHT30是一款温湿度传感器,使用IIC通信接口。可根据命令设置其测量频率、测量时间;测量持续时间有三种可选(见芯片手册2.2):         HIGH:12.5ms;         medium:4.5ms;         low:2.5ms;         测量频率有五种可选:0.5次/秒、1次/秒、2次/秒、4次/秒、

    2024年02月01日
    浏览(46)
  • 常用传感器-温湿度传感器SHT30

    SHT30温湿度传感器 工作电压:2.4V-5.5V 通讯协议:IIC 湿度测量范围:0-100 温度测量范围:-40°-125° VIN:电源正极 GND:电源负极 SCL:数据线 SDA:数据线 1.加载库文件:ClosedCube_SHT31D 选择库文件:ClosedCube_SHT31D 2.连接esp mini d1和温湿度传感器 VIN和GND分别取主板5V电压 SCL和SDA分别接

    2024年02月01日
    浏览(18)
  • 基于stm32温湿度采集平台开发

    随着现代社会的高速发展,越来越多的科学技术被应用于农业生产领域。在温湿度大棚中对温湿度、二氧化碳浓度等外部参数的实时准确的测量和调节更是保证农业高效生产的重要前提。 本次课程设计中实现了一个基丁 STM32F103VET6的智能温湿度检测系统,目的是实现温湿度的

    2024年02月02日
    浏览(20)
  • STM32+DHT11采集温湿度传感器数据

            DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度。 DHT11 与单片机之间能采用简单的单总线进行通信,仅

    2024年02月07日
    浏览(20)
  • 单片机项目分享 Stm32 WIFI智能家居温湿度和烟雾检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(26)
  • 嵌入式项目分享 Stm32 WIFI智能家居温湿度和烟雾检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月16日
    浏览(28)
  • [教程]一文搞懂STM32使用DHT11采集温湿度

          DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高 的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测 温元件,并与一个高性能8位单片机相连接。

    2024年02月01日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包