一、简介:
LTR-381RGB-01是一款数字RGB环境光传感器,具有以下特性:
-
集成RGB和ALS(环境光)检测功能
-
I2C接口(地址0x53)
-
工作电压:2.4V-3.6V
-
测量范围:0.01-64k lux
-
可编程增益和分辨率
-
内置16位ADC
-
支持红外补偿
-
低功耗模式
二、硬件接口:
LTR-381RGB-01引脚 STM32F1XX引脚 VCC 3.3V GND GND SCL PB6(I2C1_SCL) SDA PB7(I2C1_SDA) INT (可选)连接到外部中断引脚
硬件配置
-
使用STM32CubeMX配置I2C接口
-
设置适当的I2C时钟速度(建议100kHz或400kHz)
-
如果需要中断功能,配置相应的GPIO引脚
三、头文件:
#ifndef __LTR381_H__
#define __LTR381_H__
#include "stm32f1xx_hal.h"
#define LTR381_I2C_ADDR 0x53 // 7-bit I2C地址
#define LTR381_I2C_TIMEOUT 100 // I2C超时(ms)
// 寄存器地址
#define LTR381_MAIN_CTRL 0x00
#define LTR381_MEAS_RATE 0x04
#define LTR381_GAIN 0x05
#define LTR381_PART_ID 0x06
#define LTR381_MAIN_STATUS 0x07
#define LTR381_ALS_DATA 0x0D
#define LTR381_RGB_DATA 0x14
#define LTR381_INTERRUPT 0x19
// 测量模式
#define LTR381_MODE_ALS 0x02
#define LTR381_MODE_RGB 0x10
// 增益设置
#define LTR381_GAIN_1X 0x00
#define LTR381_GAIN_3X 0x01
#define LTR381_GAIN_6X 0x02
#define LTR381_GAIN_9X 0x03
#define LTR381_GAIN_18X 0x04
// 分辨率/测量速率
#define LTR381_RESOLUTION_20BIT 0x00
#define LTR381_RESOLUTION_19BIT 0x10
#define LTR381_RESOLUTION_18BIT 0x20
#define LTR381_RESOLUTION_17BIT 0x30
#define LTR381_RESOLUTION_16BIT 0x40
#define LTR381_RESOLUTION_13BIT 0x50
typedef enum {
LTR381_OK = 0,
LTR381_ERROR,
LTR381_NOT_FOUND
} LTR381_Status;
typedef struct {
I2C_HandleTypeDef *hi2c;
uint8_t address;
uint8_t mode;
uint8_t gain;
uint8_t resolution;
} LTR381_HandleTypeDef;
// 初始化函数
LTR381_Status LTR381_Init(LTR381_HandleTypeDef *hltr, I2C_HandleTypeDef *hi2c);
// 配置函数
LTR381_Status LTR381_Config(LTR381_HandleTypeDef *hltr, uint8_t mode, uint8_t gain, uint8_t resolution);
// 数据读取函数
LTR381_Status LTR381_ReadALS(LTR381_HandleTypeDef *hltr, uint32_t *als_data);
LTR381_Status LTR381_ReadRGB(LTR381_HandleTypeDef *hltr, uint32_t *red, uint32_t *green, uint32_t *blue);
float LTR381_GetLux(LTR381_HandleTypeDef *hltr, uint32_t als_data);
// 实用函数
uint8_t LTR381_ReadRegister(LTR381_HandleTypeDef *hltr, uint8_t reg);
LTR381_Status LTR381_WriteRegister(LTR381_HandleTypeDef *hltr, uint8_t reg, uint8_t value);
#endif /* __LTR381_H__ */
四、源文件:
#include "ltr381.h"
#include "math.h"
LTR381_Status LTR381_Init(LTR381_HandleTypeDef *hltr, I2C_HandleTypeDef *hi2c)
{
hltr->hi2c = hi2c;
hltr->address = LTR381_I2C_ADDR << 1; // 转换为8位地址
// 检查器件ID
uint8_t part_id = LTR381_ReadRegister(hltr, LTR381_PART_ID);
if (part_id != 0x88) {
return LTR381_NOT_FOUND;
}
// 复位器件
LTR381_WriteRegister(hltr, LTR381_MAIN_CTRL, 0x10);
HAL_Delay(10);
// 默认配置
hltr->mode = LTR381_MODE_ALS;
hltr->gain = LTR381_GAIN_3X;
hltr->resolution = LTR381_RESOLUTION_18BIT;
return LTR381_Config(hltr, hltr->mode, hltr->gain, hltr->resolution);
}
LTR381_Status LTR381_Config(LTR381_HandleTypeDef *hltr, uint8_t mode, uint8_t gain, uint8_t resolution)
{
// 设置测量模式
if (LTR381_WriteRegister(hltr, LTR381_MAIN_CTRL, mode) != LTR381_OK) {
return LTR381_ERROR;
}
// 设置增益和分辨率
uint8_t value = (resolution & 0x70) | (gain & 0x07);
if (LTR381_WriteRegister(hltr, LTR381_GAIN, value) != LTR381_OK) {
return LTR381_ERROR;
}
// 设置测量速率(与分辨率相关)
if (LTR381_WriteRegister(hltr, LTR381_MEAS_RATE, resolution) != LTR381_OK) {
return LTR381_ERROR;
}
hltr->mode = mode;
hltr->gain = gain;
hltr->resolution = resolution;
return LTR381_OK;
}
LTR381_Status LTR381_ReadALS(LTR381_HandleTypeDef *hltr, uint32_t *als_data)
{
// 确保处于ALS模式
if (hltr->mode != LTR381_MODE_ALS) {
if (LTR381_Config(hltr, LTR381_MODE_ALS, hltr->gain, hltr->resolution) != LTR381_OK) {
return LTR381_ERROR;
}
HAL_Delay(10); // 等待模式切换
}
// 检查数据是否就绪
uint8_t status = LTR381_ReadRegister(hltr, LTR381_MAIN_STATUS);
if (!(status & 0x08)) {
return LTR381_ERROR; // 数据未就绪
}
// 读取ALS数据(3字节)
uint8_t data[3];
if (HAL_I2C_Mem_Read(hltr->hi2c, hltr->address, LTR381_ALS_DATA, I2C_MEMADD_SIZE_8BIT, data, 3, LTR381_I2C_TIMEOUT) != HAL_OK) {
return LTR381_ERROR;
}
*als_data = (data[2] << 16) | (data[1] << 8) | data[0];
return LTR381_OK;
}
LTR381_Status LTR381_ReadRGB(LTR381_HandleTypeDef *hltr, uint32_t *red, uint32_t *green, uint32_t *blue)
{
// 确保处于RGB模式
if (hltr->mode != LTR381_MODE_RGB) {
if (LTR381_Config(hltr, LTR381_MODE_RGB, hltr->gain, hltr->resolution) != LTR381_OK) {
return LTR381_ERROR;
}
HAL_Delay(10); // 等待模式切换
}
// 检查数据是否就绪
uint8_t status = LTR381_ReadRegister(hltr, LTR381_MAIN_STATUS);
if (!(status & 0x08)) {
return LTR381_ERROR; // 数据未就绪
}
// 读取RGB数据(9字节: R+G+B各3字节)
uint8_t data[9];
if (HAL_I2C_Mem_Read(hltr->hi2c, hltr->address, LTR381_RGB_DATA, I2C_MEMADD_SIZE_8BIT, data, 9, LTR381_I2C_TIMEOUT) != HAL_OK) {
return LTR381_ERROR;
}
*red = (data[2] << 16) | (data[1] << 8) | data[0];
*green = (data[5] << 16) | (data[4] << 8) | data[3];
*blue = (data[8] << 16) | (data[7] << 8) | data[6];
return LTR381_OK;
}
float LTR381_GetLux(LTR381_HandleTypeDef *hltr, uint32_t als_data)
{
// 根据增益和分辨率计算照度(lux)
float sensitivity = 0.0f;
switch (hltr->gain) {
case LTR381_GAIN_1X: sensitivity = 1.0f; break;
case LTR381_GAIN_3X: sensitivity = 3.0f; break;
case LTR381_GAIN_6X: sensitivity = 6.0f; break;
case LTR381_GAIN_9X: sensitivity = 9.0f; break;
case LTR381_GAIN_18X: sensitivity = 18.0f; break;
default: sensitivity = 3.0f; // 默认增益3X
}
// 根据数据手册中的转换公式
float lux = (float)als_data * 0.6f / sensitivity;
return lux;
}
uint8_t LTR381_ReadRegister(LTR381_HandleTypeDef *hltr, uint8_t reg)
{
uint8_t value = 0;
HAL_I2C_Mem_Read(hltr->hi2c, hltr->address, reg, I2C_MEMADD_SIZE_8BIT, &value, 1, LTR381_I2C_TIMEOUT);
return value;
}
LTR381_Status LTR381_WriteRegister(LTR381_HandleTypeDef *hltr, uint8_t reg, uint8_t value)
{
if (HAL_I2C_Mem_Write(hltr->hi2c, hltr->address, reg, I2C_MEMADD_SIZE_8BIT, &value, 1, LTR381_I2C_TIMEOUT) != HAL_OK) {
return LTR381_ERROR;
}
return LTR381_OK;
}
五、示例:
#include "stm32f1xx_hal.h"
#include "ltr381.h"
#include <stdio.h>
I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART1_UART_Init(void);
LTR381_HandleTypeDef ltr381;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART1_UART_Init();
// 初始化LTR-381传感器
if (LTR381_Init(<r381, &hi2c1) != LTR381_OK) {
Error_Handler();
}
// 配置传感器: ALS模式, 增益3X, 18位分辨率
LTR381_Config(<r381, LTR381_MODE_ALS, LTR381_GAIN_3X, LTR381_RESOLUTION_18BIT);
char msg[100];
uint16_t msgLen;
uint32_t als_data;
uint32_t red, green, blue;
float lux;
while (1)
{
// 读取环境光数据
if (LTR381_ReadALS(<r381, &als_data) == LTR381_OK) {
lux = LTR381_GetLux(<r381, als_data);
msgLen = sprintf(msg, "环境光: %.2f lux\r\n", lux);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, msgLen, HAL_MAX_DELAY);
}
// 切换为RGB模式并读取数据
LTR381_Config(<r381, LTR381_MODE_RGB, LTR381_GAIN_3X, LTR381_RESOLUTION_18BIT);
HAL_Delay(50); // 等待模式切换
if (LTR381_ReadRGB(<r381, &red, &green, &blue) == LTR381_OK) {
msgLen = sprintf(msg, "RGB值 - R:%lu, G:%lu, B:%lu\r\n", red, green, blue);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, msgLen, HAL_MAX_DELAY);
}
// 切换回ALS模式
LTR381_Config(<r381, LTR381_MODE_ALS, LTR381_GAIN_3X, LTR381_RESOLUTION_18BIT);
HAL_Delay(2000); // 每2秒读取一次
}
}
// I2C1初始化函数(使用STM32CubeMX生成)
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
}
RGB_Color rgb_color;
const char* color_name;
if (LTR381_ReadRGB(<r381, &red, &green, &blue) == LTR381_OK) {
// 归一化RGB值(0-1范围)
rgb_color.r = (float)red / (float)(1 << 20); // 20位数据归一化
rgb_color.g = (float)green / (float)(1 << 20);
rgb_color.b = (float)blue / (float)(1 << 20);
color_name = DetectColor(rgb_color);
msgLen = sprintf(msg, "检测颜色: %s (R:%.2f, G:%.2f, B:%.2f)\r\n",
color_name, rgb_color.r, rgb_color.g, rgb_color.b);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, msgLen, HAL_MAX_DELAY);
}
六、RGB颜色识别:
typedef struct {
float r;
float g;
float b;
} RGB_Color;
typedef struct {
float h;
float s;
float v;
} HSV_Color;
// 将RGB值转换为HSV颜色空间
HSV_Color RGB_to_HSV(RGB_Color rgb)
{
HSV_Color hsv;
float min, max, delta;
min = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
max = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
hsv.v = max;
delta = max - min;
if (max > 0.0f) {
hsv.s = delta / max;
} else {
hsv.s = 0.0f;
hsv.h = 0.0f;
return hsv;
}
if (delta == 0.0f) {
hsv.h = 0.0f;
} else if (rgb.r >= max) {
hsv.h = (rgb.g - rgb.b) / delta;
} else if (rgb.g >= max) {
hsv.h = 2.0f + (rgb.b - rgb.r) / delta;
} else {
hsv.h = 4.0f + (rgb.r - rgb.g) / delta;
}
hsv.h *= 60.0f;
if (hsv.h < 0.0f) {
hsv.h += 360.0f;
}
return hsv;
}
// 识别主要颜色
const char* DetectColor(RGB_Color rgb)
{
HSV_Color hsv = RGB_to_HSV(rgb);
if (hsv.v < 0.1f) return "黑色";
if (hsv.s < 0.1f) return "白色";
if (hsv.h < 30) return "红色";
if (hsv.h < 90) return "黄色";
if (hsv.h < 150) return "绿色";
if (hsv.h < 210) return "青色";
if (hsv.h < 270) return "蓝色";
if (hsv.h < 330) return "品红色";
return "红色";
}