温湿度传感器驱动SHT85单⽚机STM32HAL库功能介绍:读取传感器SHT85数据,转换成温度、湿度 、饱和⽔蒸⽓含量。
注意事项:
1. SDA脚设置为开漏输出,外部上拉电阻10k。或者设置成推挽,软件切换SDA输⼊输出。
2. 调试时可适当加长延时时间。
3. 在while(1)循环之前调⽤ TH_Class_SHT85.init(),每隔1S调⽤⼀次TH_Class_SHT85.loop()。
代码
SHT85.h
#ifndef __SHT85_H__
#define __SHT85_H__
#include "main.h"
#define CRC_POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001
#define I2C_ADDR 0x44 //SHT85地址
/****************************错误码***************************/
#define NO_ERROR 0x00
#define ACK_ERROR 0x01
#define CHECKSUM_ERROR 0x02
#define TIMEOUT_ERROR 0x04
/****************************IIC错误码***************************/
typedef enum{
ACK = 0,
NO_ACK = 1,
}etI2cAck;
/
****************************CMD定义***************************/
typedef enum {
CMD_READ_SERIALNBR = 0x3780, // read rial number
CMD_READ_STATUS = 0xF32D, // read status register
CMD_CLEAR_STATUS = 0x3041, // clear status register
CMD_HEATER_ENABLE = 0x306D, // enabled heater
CMD_HEATER_DISABLE = 0x3066, // disable heater
CMD_SOFT_RESET = 0x30A2, // soft ret
CMD_MEAS_SINGLE_H = 0x2400, // single meas., high repeatability
CMD_MEAS_SINGLE_M = 0x240B, // single meas., medium repeatability
CMD_MEAS_SINGLE_L = 0x2416, // single meas., low repeatability
CMD_MEAS_PERI_05_H = 0x2032, // periodic meas. 0.5 mps, high repeatability
CMD_MEAS_PERI_05_M = 0x2024, // periodic meas. 0.5 mps, medium repeatability
CMD_MEAS_PERI_05_L = 0x202F, // periodic meas. 0.5 mps, low repeatability
CMD_MEAS_PERI_1_H = 0x2130, // periodic meas. 1 mps, high repeatability
CMD_MEAS_PERI_1_M = 0x2126, // periodic meas. 1 mps, medium repeatability
CMD_MEAS_PERI_1_L = 0x212D, // periodic meas. 1 mps, low repeatability
CMD_MEAS_PERI_2_H = 0x2236, // periodic meas. 2 mps, high repeatability
hou
CMD_MEAS_PERI_2_M = 0x2220, // periodic meas. 2 mps, medium repeatability
CMD_MEAS_PERI_2_L = 0x222B, // periodic meas. 2 mps, low repeatability
CMD_MEAS_PERI_4_H = 0x2334, // periodic meas. 4 mps, high repeatability
CMD_MEAS_PERI_4_M = 0x2322, // periodic meas. 4 mps, medium repeatability
CMD_MEAS_PERI_4_L = 0x2329, // periodic meas. 4 mps, low repeatability
CMD_MEAS_PERI_10_H = 0x2737, // periodic meas. 10 mps, high repeatability
CMD_MEAS_PERI_10_M = 0x2721, // periodic meas. 10 mps, medium repeatability
CMD_MEAS_PERI_10_L = 0x272A, // periodic meas. 10 mps, low repeatability
CMD_FETCH_DATA = 0xE000, // readout measurements for periodic mode
CMD_BREAK = 0x3093, // stop periodic measurement
}etCommands;
// Single Shot Measurement Repeatability
typedef enum {
SINGLE_MEAS_LOW = CMD_MEAS_SINGLE_L, // low repeatability
SINGLE_MEAS_MEDIUM = CMD_MEAS_SINGLE_M, // medium repeatability
SINGLE_MEAS_HIGH = CMD_MEAS_SINGLE_H // high repeatability
}etSingleMeasureModes;
// Periodic Measurement Configurations
typedef enum {
PERI_MEAS_LOW_05_HZ = CMD_MEAS_PERI_05_L,
PERI_MEAS_LOW_1_HZ = CMD_MEAS_PERI_1_L,june的音标
PERI_MEAS_LOW_2_HZ = CMD_MEAS_PERI_2_L,
PERI_MEAS_LOW_4_HZ = CMD_MEAS_PERI_4_L,
PERI_MEAS_LOW_10_HZ = CMD_MEAS_PERI_10_L,
PERI_MEAS_MEDIUM_05_HZ = CMD_MEAS_PERI_05_M,
PERI_MEAS_MEDIUM_1_HZ = CMD_MEAS_PERI_1_M,
PERI_MEAS_MEDIUM_2_HZ = CMD_MEAS_PERI_2_M,
PERI_MEAS_MEDIUM_4_HZ = CMD_MEAS_PERI_4_M,
PERI_MEAS_MEDIUM_10_HZ = CMD_MEAS_PERI_10_M,
PERI_MEAS_HIGH_05_HZ = CMD_MEAS_PERI_05_H,
PERI_MEAS_HIGH_1_HZ = CMD_MEAS_PERI_1_H,
PERI_MEAS_HIGH_2_HZ = CMD_MEAS_PERI_2_H,
PERI_MEAS_HIGH_4_HZ = CMD_MEAS_PERI_4_H,
PERI_MEAS_HIGH_10_HZ = CMD_MEAS_PERI_10_H,
}etPeriodicMeasureModes;
/****************************温湿度传感器结构体定义**************************/
typedef struct _TH_Class{
u32 SerialNumber;//传感器SN号
float Temperature;//温度
float Humidity;//相对湿度
float H2O;//绝对湿度
void (*init)(void);//初始化函数指针
void (*loop)(void);//loop函数指针,循环读取温湿度,周期:1S
}TH_Class_t;
extern TH_Class_t TH_Class_SHT85;
#endif
SHT85.c
/********************************************
*Filename: SHT85.c
*Revid: Date: 06-22 14:42
*Author: SYMBEL
*Description: SHT85驱动
*********************************************/
#include "SHT85.h"
#include <stdbool.h>
/****************************IIC引脚定义**************************/
#define SHT85_SCL(x) HAL_GPIO_WritePin(SHT85_SCK_GPIO_Port, SHT85_SCK_Pin, x?GPIO_PIN_SET:GPIO_PIN_RESET) #define SHT85_SDA(x) HAL_GPIO_WritePin(SHT85_SDA_GPIO_Port, SHT85_SDA_Pin, x?GPIO_PIN_SET:GPIO_PIN_RESET) #define IS_SHT85_SDA() HAL_GPIO_ReadPin(SHT85_SDA_GPIO_Port, SHT85_SDA_Pin) //读取SDA脚电平insulin
/****************************IIC引脚定义**************************/
/*****************************函数声明***************************/
static u8 StartWriteAccess(void);
static u8 StartReadAccess(void);
static void StopAccess(void);
static u8 WriteCommand(etCommands command);
static u8 Read2BytesAndCrc(uint16_t* data, bool finAck, uint8_t timeout); static uint8_t CalcCrc(uint8_t data[], uint8_t nbrOfBytes);
static u8 CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum); static float CalcTemperature(uint16_t rawValue);
static float CalcHumidity(uint16_t rawValue);
void SHT85_Init(void);
void SHT85_FSM(void);
/****************************结构体初始化**************************/
TH_Class_t TH_Class_SHT85 = {
she comes first.SerialNumber = 0,
.Temperature = 0.0f,
.Humidity = 0.0f,
.H2O = 0.0f,
.init = SHT85_Init,
.loop = SHT85_FSM,
};
/**********************************************************
*函数:DelayUs
*功能:延时1us
*参数:us:延时时间单位:us
*返回:⽆
*描述:⽆
**********************************************************/
static void DelayUs(u32 us)
{
for(int i=0; i<us; i++){
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__
examNOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP(); }
}
static void I2c_StartCondition(void)
{
SHT85_SDA(1);
SHT85_SCL(1);
DelayUs(3);
SHT85_SDA(0);
DelayUs(3);
SHT85_SCL(0);
DelayUs(3);
}
static void I2c_StopCondition(void)
{
SHT85_SDA(0);
SHT85_SCL(0);
DelayUs(2);
SHT85_SCL(1);
DelayUs(3);
SHT85_SDA(1);
static u8 I2c_WriteByte(uint8_t txByte)
{
uint8_t mask,error=0,i;
// SHT85_SDA(0);
for(i=1;i<20;i++);
for(mask=0x80; mask>0; mask>>=1)//shift bit for masking (8 times) {erd
if ((mask & txByte) == 0)
SHT85_SDA(0); //masking txByte, write bit to SDA-Line
el
SHT85_SDA(1);
DelayUs(1); //data hold time(t_HD;DAT)
SHT85_SCL(1); //generate clock pul on SCL
DelayUs(1); //data t-up time (t_SU;DAT)
SHT85_SCL(0);
DelayUs(1); //SCL high time (t_HIGH)
}
error = IS_SHT85_SDA(); //relea SDA-line
SHT85_SCL(1); //clk #9 for ack
DelayUs(1); //data t-up time (t_SU;DAT)
error = IS_SHT85_SDA();
SHT85_SCL(0);
DelayUs(3); //wait time to e byte package on scope
return error; //return error code
}
static uint8_t I2c_ReadByte(etI2cAck ack)
{
uint8_t mask,rxByte=0,i,rxb;
SHT85_SDA(1);
rxb = IS_SHT85_SDA(); //relea SDA-line
for(i=1;i<20;i++);
for(mask=0x80; mask>0; mask>>=1)//shift bit for masking (8 times) {
SHT85_SCL(1); //start clock on SCL-line
DelayUs(2); //data t-up time (t_SU;DAT)
rxb = IS_SHT85_SDA();
if(rxb)
rxByte=(rxByte | mask); //read bit
SHT85_SCL(0);
DelayUs(2); //data hold time(t_HD;DAT)
}
if(ack == ACK)
SHT85_SDA(0);
el
SHT85_SDA(1);
DelayUs(2); //data t-up time (t_SU;DAT)
SHT85_SCL(1); //clk #9 for ack
历届奥运会主题曲DelayUs(5); //SCL high time (t_HIGH)
SHT85_SCL(0);
//SHT85_SDA(1); //relea SDA-line
DelayUs(2); //wait time to e byte package on scope
return rxByte; //return error code
}
u8 I2c_GeneralCallRet(void)
{
I2c_StartCondition();
error = I2c_WriteByte(0x00);
if(error == NO_ERROR) {
error = I2c_WriteByte(0x06);
}
return error;
}
u8 SHT85_ReadSerialNumber(uint32_t* rialNumber)
{
u8 error; // error code
uint16_t rialNumWords[2];
error = StartWriteAccess();
/
/ write "read rial number" command
if(error == NO_ERROR) {
error = WriteCommand(CMD_READ_SERIALNBR);
}
// if no error, start read access
if(error == NO_ERROR) {
error = StartReadAccess();
}
// if no error, read first rial number word
if(error == NO_ERROR) {
error = Read2BytesAndCrc(&rialNumWords[0], true, 100);
}
// if no error, read cond rial number word
if(error == NO_ERROR) {
error = Read2BytesAndCrc(&rialNumWords[1], fal, 0);
}
StopAccess();
// if no error, calc rial number as 32-bit integer
if(error == NO_ERROR) {
*rialNumber = (rialNumWords[0] << 16) | rialNumWords[1]; }
return error;electrician
}
u8 SHT85_ReadStatus(uint16_t* status)
{
u8 error; // error code
error = StartWriteAccess();
// if no error, write "read status" command
if(error == NO_ERROR) {
error = WriteCommand(CMD_READ_STATUS);
}
// if no error, start read access
if(error == NO_ERROR) {
error = StartReadAccess();
}
// if no error, read status
if(error == NO_ERROR) {
error = Read2BytesAndCrc(status, fal, 0);
}
StopAccess();
return error;
}
u8 SHT85_ClearAllAlertFlags(void)renji
{
u8 error; // error code
error = StartWriteAccess();
// if no error, write clear status register command
violet怎么读if(error == NO_ERROR) {