基于STM32F1XX 、HAL库的LTR-381RGB-01环境光传感器驱动应用C语言程序设计

一、简介:

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                 (可选)连接到外部中断引脚

硬件配置

  1. 使用STM32CubeMX配置I2C接口

  2. 设置适当的I2C时钟速度(建议100kHz或400kHz)

  3. 如果需要中断功能,配置相应的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(&ltr381, &hi2c1) != LTR381_OK) {
        Error_Handler();
    }
    
    // 配置传感器: ALS模式, 增益3X, 18位分辨率
    LTR381_Config(&ltr381, 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(&ltr381, &als_data) == LTR381_OK) {
            lux = LTR381_GetLux(&ltr381, als_data);
            msgLen = sprintf(msg, "环境光: %.2f lux\r\n", lux);
            HAL_UART_Transmit(&huart1, (uint8_t*)msg, msgLen, HAL_MAX_DELAY);
        }
        
        // 切换为RGB模式并读取数据
        LTR381_Config(&ltr381, LTR381_MODE_RGB, LTR381_GAIN_3X, LTR381_RESOLUTION_18BIT);
        HAL_Delay(50); // 等待模式切换
        
        if (LTR381_ReadRGB(&ltr381, &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(&ltr381, 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(&ltr381, &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 "红色";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值