资讯详情

HI3861学习笔记(16)——光强度GY-30(BH1750)使用

一、简介

BH1750FVI 它是一种用于两线串行总线接口的数字光强度传感器集成电路。该集成电路可根据收集的光强数据调整液晶或键盘背景灯的亮度。利用其高分辨率,可以探测到大范围的光强度变化。

传感器特点:

  • 支持I2CBUS接口
  • 接近视觉灵敏度的光谱灵敏度特征
  • 输出相应亮度的数字值
  • 对应广泛的输入光范围。(相当于1-65535lx)
  • 通过降低功率功能,实现低电流。
  • 通过50Hz/60Hz实现除光噪声功能的稳定测定。
  • 支持1.8v逻辑输入接口。
  • 没有其他外部部件。
  • 光源依赖性弱。
  • 有两种选择I2Cslave地址。
  • 影响可调测量结果的因素是光入口大小。
  • 使用此功能计算1.1lx到100000lx马克斯/分钟范围。
  • 最小误差变化在±20%。
  • 红外线的影响很小。

1.1 测量程序步骤

1.2 指令集合

1.3 说明测量模式

二、硬件连接

功能口 引脚
SCL GPIO0
SDA GPIO1
ADDR ADDR ≥ 0.7VCC 从机地址为1011100ADDR ≤ 0.3VCC 0100011从机地址

三、添加I2C驱动

查看 HI3861学习笔记(15)——I2C接口使用

四、I2C通信流程

测量结果为2字节(高字节) High Byte 和低字节 Low Byte)计算公式为:

光强(单位)lx)=(High Byte Low Byte)/ 1.2

五、HI3861作为主机与BH1750光强传感器通信

在业务中编译BUILD.gn中包含路径

include_dirs = [         "//utils/native/lite/include",         "//kernel/liteos_m/components/cmsis/2.0",         "//base/iot_hardware/interfaces/kits/wifiiot_lite",     ] 

I2C_Init()初始化I2C后 BH1750_Init()配置BH1750连续高分辨率模式 BH1750_ReadLightIntensity()获取光强度

#include <stdio.h> #include <string.h> #include <unistd.h>  #include "ohos_init.h" #include "cmsis_os2.h" #include "wifiiot_errno.h" #include "wifiiot_gpio.h" #include "wifiiot_gpio_ex.h" #include "wifiiot_i2c.h" #include "wifiiot_i2c_ex.h"  #define I2C_TASK_STACK_SIZE 1024 * 8
#define I2C_TASK_PRIO 25

#define WRITE_BIT 0x00
#define READ_BIT 0x01

#define BH1750_SLAVE_ADDR 0x23 // 从机地址
#define BH1750_PWR_DOWN 0x00 // 关闭模块
#define BH1750_PWR_ON 0x01 // 打开模块等待测量指令
#define BH1750_RST 0x07 // 重置数据寄存器值在PowerOn模式下有效
#define BH1750_CON_H 0x10 // 连续高分辨率模式,1lx,120ms
#define BH1750_CON_H2 0x11 // 连续高分辨率模式,0.5lx,120ms
#define BH1750_CON_L 0x13 // 连续低分辨率模式,4lx,16ms
#define BH1750_ONE_H 0x20 // 一次高分辨率模式,1lx,120ms,测量后模块转到PowerDown模式
#define BH1750_ONE_H2 0x21 // 一次高分辨率模式,0.5lx,120ms,测量后模块转到PowerDown模式
#define BH1750_ONE_L 0x23 // 一次低分辨率模式,4lx,16ms,测量后模块转到PowerDown模式

/** @brief I2C驱动初始化 @param 无 @return 无 */
void I2C_Init(void)
{ 
        
    GpioInit();

    //GPIO_0复用为I2C1_SDA
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA);

    //GPIO_1复用为I2C1_SCL
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL);

    //baudrate: 400kbps
    I2cInit(WIFI_IOT_I2C_IDX_1, 400000);
}

/** @brief I2C写数据函数 @param slaveAddr -[in] 从设备地址 @param regAddr -[in] 寄存器地址 @param pData -[in] 写入数据 @param dataLen -[in] 写入数据长度 @return 错误码 */
int I2C_WriteData(uint8_t slaveAddr, uint8_t regAddr, uint8_t *pData, uint16_t dataLen)
{ 
        
    int ret;
    WifiIotI2cData i2c_data = { 
        0};

    if(0 != regAddr)
    { 
        
        i2c_data.sendBuf = &regAddr;
        i2c_data.sendLen = 1;
        ret = I2cWrite(WIFI_IOT_I2C_IDX_1, (slaveAddr << 1) | WRITE_BIT, &i2c_data);
        if(ret != 0)
        { 
        
            printf("===== Error: I2C write status1 = 0x%x! =====\r\n", ret);
            return 0;
        }
    }

    i2c_data.sendBuf = pData;
    i2c_data.sendLen = dataLen;
    ret = I2cWrite(WIFI_IOT_I2C_IDX_1, (slaveAddr << 1) | WRITE_BIT, &i2c_data);
    if(ret != 0)
    { 
        
        printf("===== Error: I2C write status1 = 0x%x! =====\r\n", ret);
        return 0;
    }

    return 1;
}

/** @brief I2C读数据函数 @param slaveAddr -[in] 从设备地址 @param regAddr -[in] 寄存器地址 @param pData -[in] 读出数据 @param dataLen -[in] 读出数据长度 @return 错误码 */
int I2C_ReadData(uint8_t slaveAddr, uint8_t regAddr, uint8_t *pData, uint16_t dataLen)
{ 
        
    int ret;
    WifiIotI2cData i2c_data = { 
        0};

    if(0 != regAddr)
    { 
        
        i2c_data.sendBuf = &regAddr;
        i2c_data.sendLen = 1;
        ret = I2cWrite(WIFI_IOT_I2C_IDX_1, (slaveAddr << 1) | WRITE_BIT, &i2c_data);
        if(ret != 0)
        { 
        
            printf("===== Error: I2C write status = 0x%x! =====\r\n", ret);
            return 0;
        }
    }

    i2c_data.receiveBuf = pData;
    i2c_data.receiveLen = dataLen;
    ret = I2cRead(WIFI_IOT_I2C_IDX_1, (slaveAddr << 1) | READ_BIT, &i2c_data);
    if(ret != 0)
    { 
        
        printf("===== Error: I2C read status = 0x%x! =====\r\n", ret);
        return 0;
    }

    return 1;
}

/** @brief BH1750初始化函数 @param 无 @return 无 */
void BH1750_Init(void)
{ 
        
    uint8_t data;
    data = BH1750_PWR_ON;              // 发送启动命令
    I2C_WriteData(BH1750_SLAVE_ADDR, 0, &data, 1);
    data = BH1750_CON_H;               // 设置连续高分辨率模式,1lx,120ms
    I2C_WriteData(BH1750_SLAVE_ADDR, 0, &data, 1);
}

/** @brief BH1750获取光强度 @param 无 @return 光强度 */
float BH1750_ReadLightIntensity(void)
{ 
        
    float lux = 0.0;
    uint8_t sensorData[2] = { 
        0};
    I2C_ReadData(BH1750_SLAVE_ADDR, 0, sensorData, 2);
    lux = (sensorData[0] << 8 | sensorData[1]) / 1.2;
    return lux;
}

static void I2CTask(void)
{ 
        
    int cnt = 0;
    float lux;

    I2C_Init();
    BH1750_Init();
    usleep(180000);                     // 设置完成后要有一段延迟

    while (1)
    { 
        
        printf("test cnt: %d", cnt++);
        lux = BH1750_ReadLightIntensity();
        printf("sensor val: %.02f [Lux]\n", lux);

        usleep(1000000);
    }
}

static void I2CExampleEntry(void)
{ 
        
    osThreadAttr_t attr;

    attr.name = "I2CTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = I2C_TASK_STACK_SIZE;
    attr.priority = I2C_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)I2CTask, NULL, &attr) == NULL)
    { 
        
        printf("Falied to create I2CTask!\n");
    }
}

APP_FEATURE_INIT(I2CExampleEntry);

查看打印:


• 由 Leung 写于 2021 年 10 月 10 日

• 参考:BH1750FVI光强度传感器及其STM32驱动程序     BH1750 STM32 驱动程序     BearPi-HM_Nano开发板传感器驱动开发——E53_SC1读取光照强度

标签: 集成电路hi1光强度传感器bh1750fvin接近传感器scl1204

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台