一、简介
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 = ®Addr;
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 = ®Addr;
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读取光照强度