|
SHT85温湿度传感器,来源https://www.mydigit.cn/thread-551616-1-1.html,刚好最近在玩时钟芯片RX8025T驱动,都是I2C总线硬件平台有了只差代码,网上搜代码无果,根据坛友分享的SHT85手册,拿出词典对着手册大概明白了几个关键点,辛苦几天终于能显示了,无奈没有读数,各种调试终不得,猛然醒悟探头坏的?量电流果然,uA级的电流都没有,让它最后道别
原来的模样
一个芯片和一个接在正负之间的电容,去掉后的光板,后背的镀金(?)铜皮挺厚的,可以剥离
芯片的背面
正面的白色膜烫掉了,封盖的是感湿核心?旁边隐约有字母
不同的角度反光
最后是读取时的显示。温和湿字没有取模,临时用压和流代用的。其它的0和1是调试验证芯片读取的中间参数。
代码用的上的拿去,唯一要求如果能用告知一下。
// -------------------------- 新增SHT85专用函数实现 --------------------------
/**
* @brief 30MHz主频下的毫秒延时(基于空循环)
* @param ms 延时毫秒数
*/
void DDelayMs(u16 ms) {
u16 i, j;
while (ms--) {
for (i = 30; i > 0; i--)
for (j = 100; j > 0; j--);
}
}
/**
* @brief CRC8校验(验证SHT85数据有效性)
* @param data 待校验数据(2字节数据+1字节CRC)
* @param len 数据长度(固定为3)
* @return 0=校验通过,1=校验失败
*/
u8 CRC8_Check(u8 *buf, u8 len) {
u8 crc = CRC8_INIT;
u8 i, j;
for (i = 0; i < len - 1; i++) { // 只处理前2字节数据
crc ^= buf;
for (j = 0; j < 8; j++) {
if (crc & 0x80) {
crc = (crc << 1) ^ CRC8_POLY;
} else {
crc <<= 1;
}
}
}
return (crc == buf[2]) ? 0 : 1;
}
/**
* @brief 发送SHT85命令(硬件I2C实现)
* @param cmd 16位命令(如SHT85_CMD_SINGLE_HIGH)
*/
void SHT85_SendCmd(u16 cmd) {
I2C_ADDR1 = (SHT85_I2C_ADDR << 1) | 0; // 写操作(最低位0)
// I2C_ADDR2 = 0x00; // SHT85无寄存器地址,仅需发送命令,此处占位
I2C_X = 2; // 发送2字节命令(MSB+LSB)
I2C_i = 0; // 缓存起始位置
// 将16位命令拆分为2字节存入I2C_1缓存
I2C_1[I2C_i++] = (cmd >> 8) & 0xFF; // 命令高字节
I2C_1[I2C_i++] = cmd & 0xFF; // 命令低字节
I2C_TX(); // 调用原有硬件I2C发送函数
}
/**
* @brief 读取SHT85数据(6字节)并校验
* @return 0=读取成功且校验通过,1=失败
*/
u8 SHT85_ReadData() {
u16 temp_raw, hum_raw;
u8 temp_buf[3], hum_buf[3];
// 步骤1:发送读命令(硬件I2C)
I2C_ADDR1 = (SHT85_I2C_ADDR << 1) | 1; // 读操作(最低位1)
// I2C_ADDR2 = 0x00; // 占位,SHT85无寄存器地址
I2C_X = 6; // 读取6字节(T_MSB,T_LSB,T_CRC,H_MSB,H_LSB,H_CRC)
I2C_i = 0; // 缓存起始位置(避开RX8025T使用的0~15字节)
I2C_RX(); // 调用原有硬件I2C接收函数
// 步骤2:提取温度和湿度数据(从I2C_1缓存中取出)
temp_buf[0] = I2C_1[16]; // T_MSB
temp_buf[1] = I2C_1[17]; // T_LSB
temp_buf[2] = I2C_1[18]; // T_CRC
hum_buf[0] = I2C_1[19]; // H_MSB
hum_buf[1] = I2C_1[20]; // H_LSB
hum_buf[2] = I2C_1[21]; // H_CRC
// 步骤3:CRC校验
if (CRC8_Check(temp_buf, 3) != 0) return 1; // 温度校验失败
if (CRC8_Check(hum_buf, 3) != 0) return 1; // 湿度校验失败
// 步骤4:组合原始数据(16位)
temp_raw = ((u16)temp_buf[0] << 8) | temp_buf[1];
hum_raw = ((u16)hum_buf[0] << 8) | hum_buf[1];
// 步骤5:换算为实际温湿度
SHT85_CalcTH(temp_raw, hum_raw);
sht85_read_ok = 1; // 读取成功标志置1
return 0;
}
/**
* @brief 温湿度换算(基于SHT85手册4.14节公式)
* @param temp_raw 温度原始值(16位)
* @param hum_raw 湿度原始值(16位)
*/
void SHT85_CalcTH(u16 temp_raw, u16 hum_raw) {
// 温度:T(℃) = -45 + 175 * (S_T / 65535)
sht85_temp = -45.0f + 175.0f * ((float)temp_raw / 65535.0f);
// 湿度:RH(%RH) = 100 * (S_RH / 65535)
sht85_hum = 100.0f * ((float)hum_raw / 65535.0f);
}
/**
* @brief SHT85完整读取流程(命令发送+等待+数据读取)
*/
void SHT85_ReadLoop() {
// 1. 先发送软复位命令(重置传感器状态,排除异常锁死)
SHT85_SendCmd(0x30A2); // SHT85软复位命令(固定值)
DDelayMs(2); // 复位需要2ms等待
SHT85_SendCmd(SHT85_CMD_SINGLE_HIGH); // 发送单次高重复性测量命令
DDelayMs(SHT85_MEAS_DELAY); // 等待测量完成(20ms足够)
if (SHT85_ReadData() != 0) { // 读取并校验数据
sht85_read_ok = 0; // 读取失败标志
}
}
void main()
{
SYS_Init();
Timer2_Init();
Lcd_init();
I2CCFG=0xE0; // I2C允许和速度控制寄存器
I2CMSST=0x00;
//主函数//********************
while (1) //下面重复循环
{
display1(); //显示程序
// 每隔1秒读取一次SHT85(利用Timer2的1ms中断计数)
if (fabc1) { // fabc1是Timer2中断的1ms标志
fabc1 = 0;
if (++sht85_cnt >= 1000) { // 1000ms = 1秒
sht85_cnt = 0;
SHT85_ReadLoop(); // 读取SHT85温湿度
}
}
}
}
void display1()
{
u8 xt = 0, yt = 0; //显示定位参数
// -------------------------- 新增SHT85温湿度显示 --------------------------
Lcd_P16x16Ch(0, 6, "压"); // 第6行第0列显示“温”
// Lcd_P16x16Ch(16, 6, "量"); // 第6行第32列显示“度”
Lcd_P16x16Ch(56, 6, "流"); // 第6行第80列显示“湿”
// Lcd_P16x16Ch(112, 6, "量"); // 第6行第112列显示“度”
// Lcd_P8x16Str(48, 6, "℃"); // 温度单位
Lcd_P8x16Str(104, 6, "%RH"); // 湿度单位
Lcd_P8x16char(0, 0, 48+sht85_read_ok);
// Lcd_P5x7int(36, 0, I2C_STATUS);
Lcd_P5x7int(72, 0, SHT85_ReadData());
Lcd_P5x7int(0, 2, hum_buf[0]);
Lcd_P5x7int(36, 2, hum_buf[1]);
Lcd_P5x7int(72, 2, hum_buf[2]);
// 显示温度(保留1位小数,如25.5℃)
if (sht85_read_ok) {
// 整数部分
Lcd_P8x16char(16, 6, 48 + (u8)sht85_temp / 10 % 10);
Lcd_P8x16char(24, 6, 48 + (u8)sht85_temp % 10);
// 小数点
Lcd_P8x16Str(32, 6, ".");
// 小数部分(四舍五入)
Lcd_P8x16char(40, 6, 48 + (u8)((sht85_temp - (u8)sht85_temp) * 10 + 0.5) % 10);
// 显示湿度(保留1位小数,如50.2%RH)
Lcd_P8x16char(72, 6, 48 + (u8)sht85_hum / 10 % 10);
Lcd_P8x16char(80, 6, 48 + (u8)sht85_hum % 10);
Lcd_P8x16Str(88, 6, ".");
Lcd_P8x16char(96, 6, 48 + (u8)((sht85_hum - (u8)sht85_hum) * 10 + 0.5) % 10);
} else {
// 读取失败时显示“--”
Lcd_P8x16Str(16, 6, "--");
Lcd_P8x16Str(32, 6, ".");
Lcd_P8x16char(40, 6, '-');
Lcd_P8x16Str(72, 6, "--");
Lcd_P8x16Str(88, 6, ".");
Lcd_P8x16char(96, 6, '-');
}
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|