日期
作者
版本
说明
2020.11.05
Tao
V1.0
1. 完成了主体内容的撰写
目录
STS-31介绍
详细参数请查看官方数据手册。
驱动源码
本驱动是基于软件模拟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温度传感器需要初始化后才能工作,因此需要在读取温度之前调用此函数。考虑到设备不存在或者通讯出错等因素,需要验证初始化设备是否成功。有两种方式可以完成验证:
- 获取此函数的返回值,0为配置失败,1为配置成功。
- 获取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博客文章一键转载插件