SHTxx系列是瑞士SENSIRION公司推出的一系列数字温湿度传感器,目前市场上常用的型号有SHT10、SHT15、SHT20、SHT21、SHT25等。
SHTxx系列传感器采用双线串行接口通讯方式,集成了高精度的温湿度传感器和信号处理电路,能够实现对环境温度和湿度的高精度和快速测量,同时具有超低功耗和长期稳定的特点。
SHTxx系列传感器广泛应用于气象、环保、家用电器、工业自动化、医疗设备、智能家居等领域,主要用于温湿度监测、控制和调节等应用场景。其优势包括精度高、稳定性好、可编程性强、响应速度快、尺寸小、易于集成等等,因此备受市场青睐。
1. CubeMX配置IICDMA
时钟配置
以上简单配置完成之后,生成MDK工程,打开。
按照时序,需要修改源码 在I2C_RequestMemoryRead函数内 添加了10ms延时
/* Wait until TXE flag is set */
if (I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
{
if (hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
/* Generate Stop */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_STOP);
}
return HAL_ERROR;
}
HAL_Delay(10); //手动添加
/* Generate Restart */
SET_BIT(hi2c->Instance->CR1, I2C_CR1_START);
/* Wait until SB flag is set */
if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK)
{
if (READ_BIT(hi2c->Instance->CR1, I2C_CR1_START) == I2C_CR1_START)
{
hi2c->ErrorCode = HAL_I2C_WRONG_START;
}
return HAL_TIMEOUT;
}
主要相关代码如下:
#define SHT4XA_RTH_Addr 0xFD //SHT4XA的温湿度寄存器地址
#define IIC2_OWN_ADDRESS7 0x88 //器件地址0x44左移1位
__packed typedef struct
{
uint8_t TempHigh8Bits;
uint8_t TempLow8Bits;
uint8_t CheckSumTemp;
uint8_t RHDataHigh8Bits;
uint8_t RHDataLow8Bits;
uint8_t CheckSum_RH_Data;
}SHT4XA_TH_Data;
SHT4XA_TH_Data sht4xaData;
HAL_I2C_Mem_Read_DMA(&hi2c2, IIC2_OWN_ADDRESS7, SHT4XA_RTH_Addr, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&sht4xaData, sizeof(sht4xaData));
SHTxxA会分别产生温度、湿度校验码,可在代码中对读取到的温湿度进行校验。校验方法如下:
/***************************CRC校验规则*********************************
(1) 预置一个值为0xFFFF的16位寄存器,此寄存器为CRC寄存器
(2) 把第一个8位二进制数与16位的CRC寄存器相异或,异或的结果存在CRC寄存器中
(3) CRC寄存器的内容左移一位,用0填补最低位,并检测移出位是0还是1
(4) 如果移出位是0,则重复步骤3,如果移出位是1,则与多项式进行异或
(5) 重复步骤3、4,直到左移8位,这样整个8位数据都进行了处理
(6) 重复步骤2~5,进行下一个字节的处理
(7)最后得到的CRC寄存器的内容即为CRC校验码
************************************************************************/
/**
******************************************************************************
* @file SHT4XA.c
* @brief 温湿度传感器CRC8校验.
* @param 校验的数据
* @param 校验数据的长度
* @retval None
*****************************************************************************/
uint8_t SHT4XA_CRC8(const uint8_t *data, int len)
{
const uint8_t POLYNOMIAL = 0x31;
uint8_t crc = 0xFF;
int i, j;
for (i=0; i<len; ++i) {
crc ^= *data++;
for (j=0; j<8; ++j) {
crc = ( crc & 0x80 )? (crc << 1) ^ POLYNOMIAL: (crc << 1);
}
}
return crc;
}
检验手册中CRC(0xBEEF)= 0x92
多项式:0x31 ( x^8+x^5+x^4+1)换成二进制为 9‘b1_0011_0001
检验:CRC(0xBEEF)= 0x92
1.第一个8位数据0xBE:CRC寄存器值为8'hFF,两者异或
1 0 1 1 1 1 1 0
XOR 1 1 1 1 1 1 1 1
————————————————————
0 1 0 0 0 0 0 1
1)左移一位,移出0,CRC值变成
1 0 0 0 0 0 1 0
2)左移一位,移出1,与多项式0x31异或
0 0 0 0 0 1 0 0
XOR 0 0 1 1 0 0 0 1
————————————————————
0 0 1 1 0 1 0 1
3)左移一位,移出0,CRC值变成
0 1 1 0 1 0 1 0
4)左移一位,移出0,CRC值变成
1 1 0 1 0 1 0 0
5)左移一位,移出1,与多项式0x31异或
1 0 1 0 1 0 0 0
XOR 0 0 1 1 0 0 0 1
————————————————————
1 0 0 1 1 0 0 1
6)左移一位,移出1,与多项式0x31异或
0 0 1 1 0 0 1 0
XOR 0 0 1 1 0 0 0 1
————————————————————
0 0 0 0 0 0 1 1
7)左移一位,移出0,CRC值变成
0 0 0 0 0 1 1 0
8)左移一位,移出0,CRC值变成
0 0 0 0 1 1 0 0
2.第二个8位数据0xEF,CRC寄存器值0x0C,两者异或:
1 1 1 0 1 1 1 1
XOR 0 0 0 0 1 1 0 0
————————————————————
1 1 1 0 0 0 1 1
1)左移一位,移出1,与多项式0x31异或
1 1 0 0 0 1 1 0
XOR 0 0 1 1 0 0 0 1
————————————————————
1 1 1 1 0 1 1 1
2)左移一位,移出1,与多项式0x31异或
1 1 1 0 1 1 1 0
XOR 0 0 1 1 0 0 0 1
————————————————————
1 1 0 1 1 1 1 1
3)左移一位,移出1,与多项式0x31异或
1 0 1 1 1 1 1 0
XOR 0 0 1 1 0 0 0 1
————————————————————
1 0 0 0 1 1 1 1
4)左移一位,移出1,与多项式0x31异或
0 0 0 1 1 1 1 0
XOR 0 0 1 1 0 0 0 1
————————————————————
0 0 1 0 1 1 1 1
5)左移一位,移出0,CRC值变成
0 1 0 1 1 1 1 0
6)左移一位,移出0,CRC值变成
1 0 1 1 1 1 0 0
7)左移一位,移出1,与多项式0x31异或
0 1 1 1 1 0 0 0
XOR 0 0 1 1 0 0 0 1
————————————————————
0 1 0 0 1 0 0 1
8)左移一位,移出0,CRC值变成
1 0 0 1 0 0 1 0
(3)可以看出CRC值最终变成了0x92.
以上如此