STS-31介绍
详细参数请查看官方数据手册。
驱动源码
本驱动是基于软件模拟I2C库设计的,利用了它提供的I2CDevice_Struct数据类型以及I2C通讯所需要的接口。
头文件
源文件
- /*
- * 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; i<STS31_DEV_NUM; i++)
- {
- STS31_Init(&STS31_DeviceArray<i>);
- }
- }
- /**
- * @brief 读取STS31的温度原始数据
- * @param sts31Dev: 需要操作的I2C设备
- * @param dataTemp: 传入需要读出的数据缓存地址(3个字节)
- * @return 读取数据的执行结果,0:读取失败;1:读取成功
- */
- uint8_t STS_ReadData(STS31_Device *sts31Dev, uint8_t *dataTemp)
- {
- 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_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;
- }</i>
复制代码
应用指南
定义并初始化设备结构体变量
- #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加热器上应用了此传感器作为温度的反馈,应该特别注意传感器配置与读取数据的有效性。当传感器失效时,应该及时的关闭加热器,以免温度调节失控。
|