首先还是先找设备地址,因为BH1750的手册是英文的,所以有点懵,简单的英文咱还是认识的,地址的英语咱还是会的,直接搜索adderss
根据手册可知地址是跟ADDR引脚的状态有关的,看下我们的原理图
可知ADDR是'L',所以写地址为0X46,读地址为0x47
#define BH1750_ADDR_WRITE 0x46 #define BH1750_ADDR_READ 0x47
当然也可以看出来BH1750的工作流程 写入工作模式,然后读取数据即可
继续看看以后什么工作模式
咦,难懂,看翻译吧,直接弄个枚举
typedef enum { POWER_OFF_CMD = 0x00, //断电:无激活状态 POWER_ON_CMD = 0x01, //通电:等待测量指令 RESET_REGISTER = 0x07, //重置数字寄存器(在断电状态下不起作用) CONT_H_MODE = 0x10, //连续H分辨率模式:在11x分辨率下开始测量,测量时间120ms CONT_H_MODE2 = 0x11, //连续H分辨率模式2:在0.51x分辨率下开始测量,测量时间120ms CONT_L_MODE = 0x13, //连续L分辨率模式:在411分辨率下开始测量,测量时间16ms ONCE_H_MODE = 0x20, //一次高分辨率模式:在11x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式 ONCE_H_MODE2 = 0x21, //一次高分辨率模式2:在0.51x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式 ONCE_L_MODE = 0x23 //一次低分辨率模式:在411x分辨率下开始测量,测量时间16ms,测量后自动设置为断电模式 } BH1750_MODE;
我们就直接使用一次高分辨率模式:在11x分辨率下开始测量,测量时间120ms,测量后自动设置为断电模式
根据流程写驱动发送指令
/** * @brief 向BH1750发送一条指令 * @param cmd —— BH1750工作模式指令(在BH1750_MODE中枚举定义) */ void BH1750_Send_Cmd(BH1750_MODE cmd) { IIC_Init(); IIC_Start(); IIC_Send_Byte(BH1750_ADDR_WRITE); IIC_Wait_Ack(); IIC_Send_Byte(cmd); IIC_Wait_Ack(); IIC_Stop(); }
读数据
/** * @brief 从BH1750接收一次光强数据 * @param dat —— 存储光照强度的地址(两个字节数组) * @retval 成功 —— 返回1 */ uint8_t BH1750_Read_Dat(uint8_t* dat) { IIC_Start(); IIC_Send_Byte(BH1750_ADDR_READ); IIC_Wait_Ack(); dat[0]=IIC_Read_Byte(1);//取高八位 dat[1]=IIC_Read_Byte(0);//取低八位 IIC_Stop(); return 1; }
数据转换
/** * @brief 将BH1750的两个字节数据转换为光照强度值(0-65535) * @param dat —— 存储光照强度的地址(两个字节数组) * @retval 成功 —— 返回光照强度值 */ uint16_t BH1750_Dat_To_Lux(uint8_t* dat) { uint16_t lux = 0; lux = dat[0]; lux <<= 8; lux += dat[1]; lux = (int)(lux / 1.2); return lux; }读取
使用一次高分辨率模式
定义一个数组存放高八位和低八位 定义一个十六进制存储光照强度
uint8_t lux[2]; uint16_t lux_16; while (1) { if(AHT10ReadData(&tem,&hum)==0) { printf("tem:%.1f\r\nhum:%d%%\r\n",tem,hum); } else { printf("aht10 not read\r\n"); } BH1750_Send_Cmd(ONCE_H_MODE);//单次模式 OLED_ShowCHinese(0u,0u,0); OLED_ShowCHinese(16u,0u,1); OLED_ShowCHinese(32u,0u,2); OLED_ShowCHinese(48u,0u,3); OLED_ShowCHinese(64u,0u,4); OLED_ShowCHinese(80u,0u,5); sprintf(buf,"tem:%.1f",tem); OLED_P8x16Str(0u,2u,(uint8_t *)buf); sprintf(buf,"hum:%d%%",hum); OLED_P8x16Str(0u,4u,(uint8_t *)buf); sprintf(buf,"lux:%d",lux_16); OLED_P8x16Str(0u,6u,(uint8_t *)buf); HAL_Delay(500); BH1750_Read_Dat(lux);//读取数据 lux_16 = BH1750_Dat_To_Lux(lux);//转换数据 printf("lux:%d\r\n",lux_16); }效果如下