[转]STM32开发项目:STS-31高精度温度传感器的驱动程序

日期

作者

版本

说明

2020.11.05

Tao

V1.0

1. 完成了主体内容的撰写

目录

STS-31介绍

详细参数请查看官方数据手册
summary

驱动源码

本驱动是基于软件模拟I2C库设计的,利用了它提供的I2CDevice_Struct数据类型以及I2C通讯所需要的接口。

头文件

/*
 * sts31.h
 *
 *  Created on: Jun 2, 2020
 *      Author: 81001
 */

#ifndef SOURCE_ALWHALESLIB_HARDWARE_INC_STS31_H_
#define SOURCE_ALWHALESLIB_HARDWARE_INC_STS31_H_

//#ifdef STS31
#include "sts31.h"
#include "i2c_virtual.h"

//Define GPIO for STS31
#define STS31_1_SCL_PORT		'E'
#define STS31_1_SCL_PIN			3
#define STS31_1_SDA_PORT		'E'
#define STS31_1_SDA_PIN			2

#define STS31_2_SCL_PORT		'E'
#define STS31_2_SCL_PIN			6
#define STS31_2_SDA_PORT		'E'
#define STS31_2_SDA_PIN			5

#define STS31_3_SCL_PORT		'F'
#define STS31_3_SCL_PIN			2
#define STS31_3_SDA_PORT		'F'
#define STS31_3_SDA_PIN			1

#define STS31_4_SCL_PORT		'F'
#define STS31_4_SCL_PIN			5
#define STS31_4_SDA_PORT		'F'
#define STS31_4_SDA_PIN			4

#define STS31_5_SCL_PORT		'A'
#define STS31_5_SCL_PIN			2
#define STS31_5_SDA_PORT		'A'
#define STS31_5_SDA_PIN			1

#define STS31_6_SCL_PORT		'A'
#define STS31_6_SCL_PIN			6
#define STS31_6_SDA_PORT		'A'
#define STS31_6_SDA_PIN			5

#define STS31_7_SCL_PORT		'C'
#define STS31_7_SCL_PIN			5
#define STS31_7_SDA_PORT		'C'
#define STS31_7_SDA_PIN			4

#define STS31_8_SCL_PORT		'F'
#define STS31_8_SCL_PIN			15
#define STS31_8_SDA_PORT		'F'
#define STS31_8_SDA_PIN			14

#define STS31_9_SCL_PORT		'E'
#define STS31_9_SCL_PIN			7
#define STS31_9_SDA_PORT		'G'
#define STS31_9_SDA_PIN			1

#define STS31_10_SCL_PORT		'E'
#define STS31_10_SCL_PIN			12
#define STS31_10_SDA_PORT		'E'
#define STS31_10_SDA_PIN		11

#define STS31_11_SCL_PORT		'E'
#define STS31_11_SCL_PIN			15
#define STS31_11_SDA_PORT		'E'
#define STS31_11_SDA_PIN		14

#define STS31_12_SCL_PORT		'B'
#define STS31_12_SCL_PIN			15
#define STS31_12_SDA_PORT		'B'
#define STS31_12_SDA_PIN		14


#define STS31_ADDRESS_0					0x4A	//ADDR PIN ->GND
#define STS31_ADDRESS_1					0x4B	//ADDR PIN ->VDD

//*************ADDR Initial********************/
#define STS31_ADDRESS				STS31_ADDRESS_0		//ADDR PIN ->GND
#define STS31_ADDRESS_W		(STS31_ADDRESS<<1) | 0x00	//write address
#define STS31_ADDRESS_R			(STS31_ADDRESS<<1) | 0x01	//read address

//single shot mode
#define STS31_SINGLE_SHOT_MODE_HIGH_REP_EN_CLKSTR				0x2C06s
#define STS31_SINGLE_SHOT_MODE_MEDIUM_REP_EN_CLKSTR				0x2C0D
#define STS31_SINGLE_SHOT_MODE_LOW_REP_EN_CLKSTR				0x2C10

#define STS31_SINGLE_SHOT_MODE_HIGH_REP_DISEN_CLKSTR			0x2400
#define STS31_SINGLE_SHOT_MODE_MEDIUM_REP_DISEN_CLKSTR			0x240B
#define STS31_SINGLE_SHOT_MODE_LOW_REP_DISEN_CLKSTR				0x2416

//continue mode
#define STS31_CONTINUE_MODE_HIGH_REP_05MPS					 			0x2032
#define STS31_CONTINUE_MODE_MEDIUM_REP_05MPS				 			0x2024
#define STS31_CONTINUE_MODE_LOW_REP_05MPS					 				0x202F

#define STS31_CONTINUE_MODE_HIGH_REP_1MPS									0x2130
#define STS31_CONTINUE_MODE_MEDIUM_REP_1MPS							0x2126
#define STS31_CONTINUE_MODE_LOW_REP_1MPS									0x212D

#define STS31_CONTINUE_MODE_HIGH_REP_2MPS									0x2236
#define STS31_CONTINUE_MODE_MEDIUM_REP_2MPS							0x2220
#define STS31_CONTINUE_MODE_LOW_REP_2MPS									0x222B

#define STS31_CONTINUE_MODE_HIGH_REP_4MPS									0x2334
#define STS31_CONTINUE_MODE_MEDIUM_REP_4MPS							0x2322
#define STS31_CONTINUE_MODE_LOW_REP_4MPS									0x2329

#define STS31_CONTINUE_MODE_HIGH_REP_10MPS								0x2737
#define STS31_CONTINUE_MODE_MEDIUM_REP_10MPS							0x2721
#define STS31_CONTINUE_MODE_LOW_REP_10MPS									0x272A

#define STS31_FETCH_DATA																			0xE000

//Break command/Stop periodic data acquisition mode
#define STS31_BREAK_CMD																0x3093

#define STS31_RESET_CMD																0x30A2
#define STS31_HEATER_EN																	0x306D
#define STS31_HEATER_DISEN															0x3066
#define STS31_READ_STATUS																0xF32D
#define STS31_CLEAR_STATUS															0x3041

#define STS31_DEV_NUM		12


typedef I2CDevice_Struct STS31_Device;

extern STS31_Device STS31_DeviceArray[STS31_DEV_NUM];


uint8_t STS31_Init(STS31_Device *sts31Dev);
void STS31_InitAll();

uint8_t  STS_ReadData(STS31_Device *sts31Dev, uint8_t *dataTemp);
float STS_GetTemperature(STS31_Device *sts31Dev);

//#endif
#endif /* SOURCE_ALWHALESLIB_HARDWARE_INC_STS31_H_ */

源文件

/*
 * sts31.c
 *
 *  Created on: Jun 2, 2020
 *      Author: 81001
 */
#include "sts31.h"
#include "check.h"

STS31_Device STS31_DeviceArray[STS31_DEV_NUM]=
{
	{.port = {.SclPort=STS31_1_SCL_PORT,.SclPin=STS31_1_SCL_PIN,.SdaPort=STS31_1_SDA_PORT,.SdaPin=STS31_1_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_2_SCL_PORT,.SclPin=STS31_2_SCL_PIN,.SdaPort=STS31_2_SDA_PORT,.SdaPin=STS31_2_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_3_SCL_PORT,.SclPin=STS31_3_SCL_PIN,.SdaPort=STS31_3_SDA_PORT,.SdaPin=STS31_3_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_4_SCL_PORT,.SclPin=STS31_4_SCL_PIN,.SdaPort=STS31_4_SDA_PORT,.SdaPin=STS31_4_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_5_SCL_PORT,.SclPin=STS31_5_SCL_PIN,.SdaPort=STS31_5_SDA_PORT,.SdaPin=STS31_5_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_6_SCL_PORT,.SclPin=STS31_6_SCL_PIN,.SdaPort=STS31_6_SDA_PORT,.SdaPin=STS31_6_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_7_SCL_PORT,.SclPin=STS31_7_SCL_PIN,.SdaPort=STS31_7_SDA_PORT,.SdaPin=STS31_7_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_8_SCL_PORT,.SclPin=STS31_8_SCL_PIN,.SdaPort=STS31_8_SDA_PORT,.SdaPin=STS31_8_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_9_SCL_PORT,.SclPin=STS31_9_SCL_PIN,.SdaPort=STS31_9_SDA_PORT,.SdaPin=STS31_9_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_10_SCL_PORT,.SclPin=STS31_10_SCL_PIN,.SdaPort=STS31_10_SDA_PORT,.SdaPin=STS31_10_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_11_SCL_PORT,.SclPin=STS31_11_SCL_PIN,.SdaPort=STS31_11_SDA_PORT,.SdaPin=STS31_11_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_12_SCL_PORT,.SclPin=STS31_12_SCL_PIN,.SdaPort=STS31_12_SDA_PORT,.SdaPin=STS31_12_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
};


/**
 * @brief 初始化STS31温度传感器
 * 		由于STS31温度传感器需要初始化后才能工作,因此需要在读取温度之前调用此函数。
 * 		考虑到设备不存在或者通讯出错等因素,需要验证初始化设备是否成功。
 * 		有两种方式可以完成验证:1. 获取此函数的返回值 2. 获取STS31_Device的devStatus成员的值。
 * 		推荐采用第二种方式验证是否完成配置。此值也可用作STS31的插拔检测。
 * @param sts31Dev: 需要初始化的I2C设备
 * @return 初始化的结果(0:初始化失败,1:初始化成功)
 */
uint8_t STS31_Init(STS31_Device *sts31Dev)
{

	I2C_Virtual_SetPin(sts31Dev->port.SdaPort, sts31Dev->port.SdaPin, sts31Dev->port.SclPort, sts31Dev->port.SclPin);

	I2C_Virtual_Start();																	//启动总线
	I2C_Virtual_SendByte(sts31Dev->address<<0x01 | 0x00);				//发送器件地址(写)

	if (I2C_Virtual_ack == 0)
	{
		sts31Dev->devStatus = 0;
		return 0;
	}

	I2C_Virtual_SendByte((STS31_CONTINUE_MODE_MEDIUM_REP_2MPS >> 8) & 0xFF);

	if (I2C_Virtual_ack == 0)
	{
		sts31Dev->devStatus = 0;
		return 0;
	}

	I2C_Virtual_SendByte(STS31_CONTINUE_MODE_MEDIUM_REP_2MPS & 0xFF);

	if (I2C_Virtual_ack == 0)
	{
		sts31Dev->devStatus = 0;
		return 0;
	}

	I2C_Virtual_Stop();

	sts31Dev->devStatus = 1;
	return 1;
}


/**
 * 将STS31_DeviceArray中的成员依次进行初始化
 */
void STS31_InitAll()
{
	for(uint8_t i = 0; iport.SdaPort, sts31Dev->port.SdaPin, sts31Dev->port.SclPort, sts31Dev->port.SclPin);

	I2C_Virtual_Start();																//启动总线
	I2C_Virtual_SendByte(sts31Dev->address<<0x01 | 0x00);			//发送器件地址(写)

	if (I2C_Virtual_ack == 0)
	{
		sts31Dev->devStatus = 0;
		return 0;
	}


	I2C_Virtual_SendByte((STS31_FETCH_DATA >> 8) & 0xFF);

	if (I2C_Virtual_ack == 0)
	{
		sts31Dev->devStatus = 0;
		return 0;
	}


	I2C_Virtual_SendByte(STS31_FETCH_DATA & 0xFF);

	if (I2C_Virtual_ack == 0)
	{
		sts31Dev->devStatus = 0;
		return 0;
	}

	I2C_Virtual_Stop();

	delay_us(10);

	I2C_Virtual_Start();															//启动总线
	I2C_Virtual_SendByte(sts31Dev->address<<0x01 | 0x01);		//发送器件地址(读)

	if (I2C_Virtual_ack == 0)
	{
		sts31Dev->devStatus = 0;
		return 0;
	}

	dataTemp[0] = I2C_Virtual_RcvByte();								//接收数据
	I2C_Virtual_Ack();															//发送就答位

	dataTemp[1] = I2C_Virtual_RcvByte();
	I2C_Virtual_Ack();															//发送就答位

	dataTemp[2] = I2C_Virtual_RcvByte();
	I2C_Virtual_NoAck();													//发送非应位

	I2C_Virtual_Stop(); 														//结束总线

	sts31Dev->devStatus = 1;
	return 1;
}


/**
 * @brief 读取STS31的温度数据
 * 		由STS_ReadData函数进一步封装得到,需要特别注意的是,如果读取出错将会返回919。
 * @param sts31Dev: 需要操作的I2C设备
 * @return 温度数值(float类型)
 */
float STS_GetTemperature(STS31_Device *sts31Dev)
{
	float data = 0;
	uint8_t dataTemp[3] = { 0 };

	STS_ReadData(sts31Dev, dataTemp);

	if (CheckCRC8(dataTemp, 3) != 0)
	{
		data = (-45 + 175 * (dataTemp[0] * 256 + dataTemp[1]) / 65535.0);
	}
	else
	{
		data = 919;
	}

	return data;
}

应用指南

定义并初始化设备结构体变量

#define STS31_DEV_NUM		12
typedef I2CDevice_Struct STS31_Device;

//Define GPIO for STS31
#define STS31_1_SCL_PORT		'E'
#define STS31_1_SCL_PIN			3
#define STS31_1_SDA_PORT		'E'
#define STS31_1_SDA_PIN			2

#define STS31_2_SCL_PORT		'E'
#define STS31_2_SCL_PIN			6
#define STS31_2_SDA_PORT		'E'
#define STS31_2_SDA_PIN			5

#define STS31_3_SCL_PORT		'F'
#define STS31_3_SCL_PIN			2
#define STS31_3_SDA_PORT		'F'
#define STS31_3_SDA_PIN			1

#define STS31_4_SCL_PORT		'F'
#define STS31_4_SCL_PIN			5
#define STS31_4_SDA_PORT		'F'
#define STS31_4_SDA_PIN			4

#define STS31_5_SCL_PORT		'A'
#define STS31_5_SCL_PIN			2
#define STS31_5_SDA_PORT		'A'
#define STS31_5_SDA_PIN			1

#define STS31_6_SCL_PORT		'A'
#define STS31_6_SCL_PIN			6
#define STS31_6_SDA_PORT		'A'
#define STS31_6_SDA_PIN			5

#define STS31_7_SCL_PORT		'C'
#define STS31_7_SCL_PIN			5
#define STS31_7_SDA_PORT		'C'
#define STS31_7_SDA_PIN			4

#define STS31_8_SCL_PORT		'F'
#define STS31_8_SCL_PIN			15
#define STS31_8_SDA_PORT		'F'
#define STS31_8_SDA_PIN			14

#define STS31_9_SCL_PORT		'E'
#define STS31_9_SCL_PIN			7
#define STS31_9_SDA_PORT		'G'
#define STS31_9_SDA_PIN			1

#define STS31_10_SCL_PORT		'E'
#define STS31_10_SCL_PIN		12
#define STS31_10_SDA_PORT		'E'
#define STS31_10_SDA_PIN		11

#define STS31_11_SCL_PORT		'E'
#define STS31_11_SCL_PIN		15
#define STS31_11_SDA_PORT		'E'
#define STS31_11_SDA_PIN		14

#define STS31_12_SCL_PORT		'B'
#define STS31_12_SCL_PIN		15
#define STS31_12_SDA_PORT		'B'
#define STS31_12_SDA_PIN		14

extern STS31_Device STS31_DeviceArray[STS31_DEV_NUM];

STS31_Device STS31_DeviceArray[STS31_DEV_NUM]=
{
	{.port = {.SclPort=STS31_1_SCL_PORT,.SclPin=STS31_1_SCL_PIN,.SdaPort=STS31_1_SDA_PORT,.SdaPin=STS31_1_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_2_SCL_PORT,.SclPin=STS31_2_SCL_PIN,.SdaPort=STS31_2_SDA_PORT,.SdaPin=STS31_2_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_3_SCL_PORT,.SclPin=STS31_3_SCL_PIN,.SdaPort=STS31_3_SDA_PORT,.SdaPin=STS31_3_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_4_SCL_PORT,.SclPin=STS31_4_SCL_PIN,.SdaPort=STS31_4_SDA_PORT,.SdaPin=STS31_4_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_5_SCL_PORT,.SclPin=STS31_5_SCL_PIN,.SdaPort=STS31_5_SDA_PORT,.SdaPin=STS31_5_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_6_SCL_PORT,.SclPin=STS31_6_SCL_PIN,.SdaPort=STS31_6_SDA_PORT,.SdaPin=STS31_6_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_7_SCL_PORT,.SclPin=STS31_7_SCL_PIN,.SdaPort=STS31_7_SDA_PORT,.SdaPin=STS31_7_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_8_SCL_PORT,.SclPin=STS31_8_SCL_PIN,.SdaPort=STS31_8_SDA_PORT,.SdaPin=STS31_8_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_9_SCL_PORT,.SclPin=STS31_9_SCL_PIN,.SdaPort=STS31_9_SDA_PORT,.SdaPin=STS31_9_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_10_SCL_PORT,.SclPin=STS31_10_SCL_PIN,.SdaPort=STS31_10_SDA_PORT,.SdaPin=STS31_10_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_11_SCL_PORT,.SclPin=STS31_11_SCL_PIN,.SdaPort=STS31_11_SDA_PORT,.SdaPin=STS31_11_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
	{.port = {.SclPort=STS31_12_SCL_PORT,.SclPin=STS31_12_SCL_PIN,.SdaPort=STS31_12_SDA_PORT,.SdaPin=STS31_12_SDA_PIN}, .address = STS31_ADDRESS, .devStatus = 0},
};

配置STS-31芯片

在工程的合适位置调用void STS31_InitAll()uint8_t STS31_Init(STS31_Device *sts31Dev)完成初始化。初始化函数按照默认的配置方式STS31_CONTINUE_MODE_MEDIUM_REP_2MPS)对芯片进行初始化,如果需要其他的配置方式需要重写此函数。

需要特别注意的是由于STS31温度传感器需要初始化后才能工作,因此需要在读取温度之前调用此函数。考虑到设备不存在或者通讯出错等因素,需要验证初始化设备是否成功。有两种方式可以完成验证:

  1. 获取此函数的返回值,0为配置失败,1为配置成功。
  2. 获取STS31_Device的devStatus成员的值。

推荐采用第二种方式验证是否完成配置。此值也可用作STS31的插拔检测,即当sts31Dev->devStatus = 0时,可认为通讯失败或者器件不存在,此时可以选择周期性的轮询初始化函数,以检测STS-31芯片是否恢复工作。

读取STS-31温度

在工程合适位置调用uint8_t STS_ReadData(STS31_Device *sts31Dev, uint8_t *dataTemp)float STS_GetTemperature(STS31_Device *sts31Dev)。后面的函数是对前面的封装,可以直接调用以获取传感器采集的温度数据,如果采集或通讯出错,将返回数值919

特别说明

如果在PCB加热器上应用了此传感器作为温度的反馈,应该特别注意传感器配置与读取数据的有效性。当传感器失效时,应该及时的关闭加热器,以免温度调节失控。

---------------------
作者:全能骑士涛锅锅
来源:CSDN
原文:https://knighttao.blog.csdn.net/article/details/109519659
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值