STM32F103C8T6 · HAL库 · 软件I2C通信
16位数字光照强度传感器 · 1-65535 lx 测量范围
BH1750FVI 是一款用于 I2C总线接口 的数字环境光传感器 IC。芯片内部集成了光敏二极管(Photodiode),当可见光照射到光敏二极管表面时,产生与光强度成正比的光电流。该光电流经过内部16位ADC(模数转换器)转换为数字值,再通过数字电路进行光谱响应补偿计算,最终输出以勒克斯(lx)为单位的数字光照强度值。
BH1750 的光谱响应曲线经过专门设计,接近人眼视觉灵敏度曲线(峰值约540nm),能够准确感知人眼所感受的环境亮度,广泛用于手机、显示器背光调节、智能家居照明等场景。传感器支持连续测量和单次测量两种工作模式,高分辨率模式下测量时间约120ms,分辨率可达1 lx。
测量范围 1-65535 lx,覆盖从夜间微光到晴天直射阳光的全部场景,16位高精度ADC确保数据准确。
光谱灵敏度经过校准,接近人眼视觉特性(V(λ)曲线),感知结果与人眼感受高度一致。
标准I2C总线接口,地址可选(0x23/0x5C),直接输出数字光照值,无需复杂模拟信号处理。
支持断电模式(Power Down),待机电流极低,适合电池供电的便携式设备长时间运行。
| 引脚 | 名称 | 功能 | STM32连接 |
|---|---|---|---|
| VCC | 电源正极 | 模块供电 (3V-5V) | 3.3V |
| GND | 电源地 | 公共接地 | GND |
| SCL | I2C时钟线 | 串行时钟信号 | PB1 |
| SDA | I2C数据线 | 串行数据信号 | PB0 |
| ADDR | 地址选择 | I2C地址选择 (低=0x23, 高=0x5C) | GND (低电平) |
int main(void) { HAL_Init(); // 初始化HAL库 SystemClock_Config(); // 配置系统时钟 72MHz MX_GPIO_Init(); // 使能GPIO时钟 OLED_Init(); // 初始化OLED显示屏 (PB14/PB15) BH1750_GPIO_Init(); // 初始化BH1750引脚 (PB0/PB1) while (1) { // 主循环逻辑见 4.7节 } }
void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 8MHz × 9 = 72MHz HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // HCLK = 72MHz RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // APB1 = 36MHz RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // APB2 = 72MHz HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); }
void BH1750_GPIO_Init(void) { BH1750_SCL_GPIO_CLK_ENABLE(); // 使能GPIOB时钟 BH1750_SDA_GPIO_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; // SCL - PB1 推挽输出 GPIO_InitStruct.Pin = BH1750_SCL_Pin; // GPIO_PIN_1 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BH1750_SCL_GPIO_Port, &GPIO_InitStruct); // SDA - PB0 推挽输出 GPIO_InitStruct.Pin = BH1750_SDA_Pin; // GPIO_PIN_0 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BH1750_SDA_GPIO_Port, &GPIO_InitStruct); Single_Write_BH1750(0x01); // 上电命令 HAL_Delay(180); // 等待芯片稳定 bh_data_send(BHPowOn); // 发送Power On }
void BH1750_IIC_Start(void) { BH1750_SDA_OUT(); // SDA设为输出模式 BH1750_SDA_DATA(1); // SDA拉高 BH1750_SCL_OUT(1); // SCL拉高 delay_us(4); BH1750_SDA_DATA(0); // SCL高时SDA下降沿 = START delay_us(4); BH1750_SCL_OUT(0); // 钳住I2C总线 }
(txd & 0x80) >> 7 提取最高位,设置SDA电平后,SCL产生上升沿发送数据位,然后拉低SCL。循环8次完成一个字节的传输。
void BH1750_IIC_Send_Byte(uint8_t txd) { uint8_t t; BH1750_SDA_OUT(); BH1750_SCL_OUT(0); // 拉低时钟开始传输 for(t = 0; t < 8; t++) { if((txd & 0x80) >> 7) BH1750_SDA_DATA(1); // 发送1 else BH1750_SDA_DATA(0); // 发送0 txd <<= 1; // 左移一位 delay_us(2); BH1750_SCL_OUT(1); // SCL上升沿 - 从机读取数据 delay_us(2); BH1750_SCL_OUT(0); // SCL下降沿 delay_us(2); } }
lux = (高字节×256 + 低字节) / 1.2。
uint16_t bh1750_read(void) { uint16_t light; bh_data_send(BHReset); // 0x07 - 复位命令 bh_data_send(BHModeH1); // 0x10 - 连续高分辨率模式 (1lx) HAL_Delay(180); // 等待ADC转换完成 (约120ms + 余量) light = bh_data_read(); // 读取2字节数据 light = light / 1.2; // 转换为勒克斯(lx)单位 return light; }
HAL_GetTick() 获取系统毫秒时间戳,每 500ms 执行一次光照读取和显示更新。流程为:读取BH1750光照值 → 清屏 → 居中显示"光照:XXX lx" → 更新OLED显示 → 更新时间戳。
while (1) { if(HAL_GetTick() - Time_Now >= 500) // 500ms更新一次 { light = bh1750_read(); // 读取光照值 (lx) OLED_Clear(); // 清屏 OLED_CenterPrintf(24, "光照:%d lx", light); // 居中显示 OLED_Update(); // 更新OLED显示 Time_Now = HAL_GetTick(); // 更新时间戳 } }
| 命令名称 | 代码 | 说明 |
|---|---|---|
| BHPowDown | 0x00 | 断电模式,停止测量 |
| BHPowOn | 0x01 | 上电,准备接收指令 |
| BHReset | 0x07 | 复位,清除状态寄存器 |
| BHModeH1 | 0x10 | 连续高分辨率模式 (1lx, 120ms) |
| BHModeH2 | 0x11 | 连续高分辨率模式2 (0.5lx, 120ms) |
| BHModeL | 0x13 | 连续低分辨率模式 (4lx, 16ms) |
| BHSigModeH | 0x20 | 单次高分辨率模式 (测量后自动断电) |
| BHSigModeH2 | 0x21 | 单次高分辨率模式2 (测量后自动断电) |
| BHSigModeL | 0x23 | 单次低分辨率模式 (测量后自动断电) |
| 光照范围 (lx) | 等级 | 典型场景 |
|---|---|---|
| < 10 | 很暗 | 夜间环境、无光源 |
| 10 - 100 | 较暗 | 昏暗走廊、月光下 |
| 100 - 500 | 正常 | 普通室内照明、办公室 |
| 500 - 1000 | 明亮 | 明亮室内、超市照明 |
| 1000 - 10000 | 很亮 | 阴天户外、窗边 |
| > 10000 | 极亮 | 晴天阳光直射 |