STM32cubemx配置硬件IIC如图所示
SHT40的驱动代码
#include "SHT40.h" #include "i2c.h" #include <rtthread.h> #include <rtdbg.h> #define SHT40_ADDR_WRITE 0x44<<1 //10001000 #define SHT40_ADDR_READ (0x44<<1)+1 //10001011 #define CRC8_POLYNOMIAL 0x31 uint8_t SHT40_CheckCrc8(uint8_t* const message, uint8_t initial_value) { uint8_t remainder; //余数 uint8_t i = 0, j = 0; //循环变量 /* 初始化 */ remainder = initial_value; for(j = 0; j < 2;j++) { remainder ^= message[j]; /* 从最高位开始依次计算 */ for (i = 0; i < 8; i++) { if (remainder & 0x80) { remainder = (remainder << 1)^CRC8_POLYNOMIAL; } else { remainder = (remainder << 1); } } } /* 返回计算的CRC码 */ return remainder; } /** * @brief 向SHT40发送一条指令(16bit) * @param cmd —— SHT40指令(在etCommands中枚举定义) * @retval 成功返回HAL_OK */ static uint8_t SHT40_Send_Cmd(SHT40Command cmd) { uint8_t cmd_buffer = 0; cmd_buffer = cmd ; return HAL_I2C_Master_Transmit(&hi2c1, SHT40_ADDR_WRITE, (uint8_t*)&cmd_buffer, 1, 0x00FF); } /** * @brief 复位SHT40 * @param none * @retval none */ void SHT40_reset(void) { SHT40_Send_Cmd(SHT4X_CMD_SOFT_RESET); // HAL_Delay(20); rt_thread_mdelay(20); } /** * @brief 初始化SHT40 * @param none * @retval 成功返回HAL_OK * @note 周期测量模式 */ uint8_t SHT40_Init(void) { return SHT40_Send_Cmd(SHT4X_CMD_MEASURE_HPM); } /** * @brief 从SHT40读取一次数据 * @param dat —— 存储读取数据的地址(6个字节数组) * @retval 成功 —— 返回HAL_OK */ uint8_t SHT40_Read_Dat(uint8_t* dat) { SHT40_Send_Cmd(SHT4X_CMD_MEASURE_HPM); rt_thread_mdelay(10); return HAL_I2C_Master_Receive(&hi2c1, SHT40_ADDR_READ, dat, 6, 0xFFFF); } /** * @brief 将SHT40接收的6个字节数据进行CRC校验,并转换为温度值和湿度值 * @param dat —— 存储接收数据的地址(6个字节数组) * @retval 校验成功 —— 返回0 * 校验失败 —— 返回1,并设置温度值和湿度值为0 */ uint8_t SHT40_Dat_To_Float(uint8_t* const dat, float* temperature, float* humidity) { uint16_t recv_temperature = 0; uint16_t recv_humidity = 0; /* 校验温度数据和湿度数据是否接收正确 */ if(SHT40_CheckCrc8(dat, 0xFF) != dat[2] || SHT40_CheckCrc8(&dat[3], 0xFF) != dat[5]) return 1; /* 转换温度数据 */ recv_temperature = ((uint16_t)dat[0]<<8)|dat[1]; *temperature = -45 + 175*((float)recv_temperature/65535); /* 转换湿度数据 */ recv_humidity = ((uint16_t)dat[3]<<8)|dat[4]; *humidity = -6 + 125 * ((float)recv_humidity / 65535); if(*humidity>=100) //根据数据手册编写 *humidity=100; else if(*humidity<=0) *humidity=0; return 0; }
#ifndef __SHT40_H__ #define __SHT40_H__ #include "main.h" // Sensor Commands typedef enum { SHT4X_CMD_MEASURE_HPM = 0xFD, //measure T & RH with high precision (high repeatability) SHT4X_CMD_MEASURE_MPM = 0xF6, //measure T & RH with medium precision (medium repeatability) SHT4X_CMD_MEASURE_LPM = 0xE0, //measure T & RH with lowest precision (low repeatability) SHT4X_CMD_READ_SERIAL = 0x89, //read serial number SHT4X_CMD_SOFT_RESET = 0x94, //soft reset SHT4X_CMD_200W_1S = 0x39, //activate heater with 200mW for 1s, including a high precision measurement just before deactivation SHT4X_CMD_200W_01S = 0x32, //activate heater with 200mW for 0.1s including a high precision measurement just before deactivation SHT4X_CMD_110W_1S = 0x2F, //activate heater with 110mW for 1s including a high precision measurement just before deactivation SHT4X_CMD_110W_01S = 0x24, //activate heater with 110mW for 0.1s including a high precision measurement just before deactivation SHT4X_CMD_20W_1S = 0x1E, //activate heater with 20mW for 1s including a high precision measurement just before deactivation SHT4X_CMD_20W_01S = 0x15, //activate heater with 20mW for 0.1s including a high precision measurement just before deactivation }SHT40Command; uint8_t SHT40_CheckCrc8(uint8_t* const message, uint8_t initial_value); uint8_t SHT40_Init(void); void SHT40_reset(void); uint8_t SHT40_Read_Dat(uint8_t* dat); uint8_t SHT40_Dat_To_Float(uint8_t* const dat, float* temperature, float* humidity); #endif
注意:在读sht40的寄存器之后一定要加10几个ms的延时
————————————————
版权声明:本文为CSDN博主「吃什么都胖」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_50173542/article/details/129404085