STM32H750B使用VEML6070(UV3 Click)传感器时MSB读取失败求助
VEML6070 MSB读取失败问题修复方案
核心问题分析
你代码里的I2C地址定义错误是导致MSB读取失败的主要原因,另外读取逻辑也存在优化空间:
- 你把LSB的读地址写成了写地址(
0x38<<1是写地址0x70,但读LSB需要用带读位的地址0x71) - 分开读取MSB和LSB容易出现时序问题,建议用连续读取方式
修正步骤
1. 修正I2C地址定义
替换你原来的地址宏定义,确保读写地址正确:
// VEML6070 8位I2C地址(HAL库要求传入8位地址,包含读写位) #define VEML6070_ADDR_WRITE 0x70 // 0x38 << 1,写命令/配置用 #define VEML6070_ADDR_READ_LSB 0x71 // 0x38 << 1 | 1,读LSB数据用 #define VEML6070_ADDR_READ_MSB 0x73 // 0x39 << 1 | 1,读MSB数据用(这个你原来的定义是对的) #define VEML6070_CMD_IT_2T 0x0C // 积分时间2T(200ms)
2. 优化读取逻辑
用连续读取一次性获取LSB和MSB,减少时序问题,同时修正数据拼接逻辑:
uint8_t cmd = VEML6070_CMD_IT_2T; uint16_t uv_raw; // 用16位变量存储,避免8位溢出 float uv_index; HAL_StatusTypeDef ret = HAL_I2C_IsDeviceReady(&hi2c4, VEML6070_ADDR_WRITE, 3, 1000); if (ret != HAL_OK) { snprintf(SendBuffer4, sizeof(SendBuffer4), "Device not ready"); } else { // 发送配置命令 ret = HAL_I2C_Master_Transmit(&hi2c4, VEML6070_ADDR_WRITE, &cmd, 1, 1000); if (ret != HAL_OK) { snprintf(SendBuffer4, sizeof(SendBuffer4), "Config send failed"); } else { // 等待积分完成(2T模式需要200ms,延迟300ms留余量) HAL_Delay(300); // 连续读取LSB和MSB uint8_t raw_data[2]; ret = HAL_I2C_Master_Receive(&hi2c4, VEML6070_ADDR_READ_LSB, raw_data, 2, 1000); if (ret != HAL_OK) { snprintf(SendBuffer4, sizeof(SendBuffer4), "Data read failed"); } else { // 拼接16位原始数据:MSB左移8位 + LSB uv_raw = (raw_data[1] << 8) | raw_data[0]; // 转换为UV指数(数据手册规定2T模式下,UV指数 = 原始值 / 10) uv_index = uv_raw / 10.0f; snprintf(SendBuffer4, sizeof(SendBuffer4), "UV Index: %.1f", uv_index); } } }
3. 硬件与初始化检查
- 确认UV3 Click模块的SDA、SCL引脚正确连接到STM32H750的I2C4对应引脚
- 检查I2C初始化配置:时钟频率不超过400kHz,引脚设置为开漏输出+上拉(软件或硬件上拉均可)
- 模块自带上拉电阻,无需额外添加,但如果是飞线连接,确保线路无松动
内容的提问来源于stack exchange,提问作者Long Lost Hero
相关产品推荐
相关产品推荐

