一、簡介
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 從機位址為”1011100“ ADDR ≤ 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讀取光照強度