简介
BH1570FVI是一款常用的光照强度传感器,通过IIC接口协议和芯片通信,具有16位的转换精度,光照强度范围为(1-65535lx)。
电路介绍
关于芯片的引脚如上图所示:芯片供电电压为2.0-3.6V,其中DVI引脚是芯片的复位引脚,SCL为IIC时钟引脚,SDA为IIC数据引脚,ADDR为芯片的地址引脚,当接低电平时芯片的地址为0X46,当接低电平时芯片地址为0XB8,ADDR悬空时地址为0X46。
数据读取介绍
BH1570FVI具有三种测量模式
测量模式 | 测量时间 | 分辨率 |
---|---|---|
高分辨率模式2 | 120ms | 0.5lx |
高分辨率模式 | 120ms | 1lx |
低分辨率模式 | 16ms | 4lx |
其中高分辨率模式,适合在黑暗环境下的测试,光照强度小于10lx的时候。对于每种测量模式又分为单次测量和连续测量模式,单次测量模式和连续测量模块之间的区别是,使用单次测量模式测量会在测量后将BH1570设为掉电模式,以减小功耗。
程序
BH1570.H
#ifndef __BH1570_H_
#define __BH1570_H_
#include "sys.h"
/*********************命令定义*******************/
#define BHAddr 0x46 //从机地址
#define BHAddWrite BHAddr //写数据指令
#define BHAddRead BHAddr+1 //读数据指令
#define BHPowDown 0x00 //关闭模块
#define BHPowOn 0x01 //打开模块等待测量指令
#define BHReset 0x07 //重置数据寄存器值在PowerOn模式下有效
#define BHModeH1 0x10 //高分辨率 单位1lx 测量时间120ms
#define BHModeH2 0x11 //高分辨率模式2 单位0.5lx 测量时间120ms
#define BHModeL 0x13 //低分辨率 单位4lx 测量时间16ms
#define BHSigModeH 0x20 //一次高分辨率 测量 测量后模块转到 PowerDown模式
#define BHSigModeH2 0x21 //一次高分辨率 测量 测量后模块转到 PowerDown模式
#define BHSigModeL 0x23 // 低分辨率 测量后模块转到 PowerDown模式
/******************外部函数声明*******************/
void BH1570_Init(u8 mode);
void BhSendCommand(u8 command);
u8 CheckBh(void);
u16 BhSigRead(u8 mode);
u16 BhRead(void);
#endif
BH1570.C
在这里插入代码片#include "BH1570.H"
#include "myiic.h"
#include "delay.h"
/*
brief BH1570初始化函数
param mode 设置读的模式
连续读(BHModeH1/BHModeH2/BHModeL) 单次读(BHSigModeH/BHSigModeH2/BHSigModeL)
return None
**/
void BH1570_Init(u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOBA
GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4); //PA4 输出高
BhSendCommand(BHPowOn); //发送启动命令
BhSendCommand(BHReset); //清除寄存器内容
BhSendCommand(mode); //设置高精度为模式2
delay_ms(180); //设置完成后要有一段延迟,手册上说最大180ms就可以了
}
/*
brief 检查BH1570是否存在
param None
return 存在返回0,否者返回1
**/
u8 CheckBh()
{
u8 ack=1;;
IIC_Start();
IIC_Send_Byte(BHAddr);
ack=IIC_Wait_Ack();
IIC_Stop();
return ack;
}
/*
brief BH1570发送命令
param command 需要发送的命令
return 存在返回0,否者返回1
**/
void BhSendCommand(u8 command)
{
IIC_Start(); //iic起始信号
IIC_Send_Byte(BHAddWrite); //发送器件地址
IIC_Wait_Ack(); //等待从机应答
IIC_Send_Byte(command); //发送指令
IIC_Wait_Ack(); //等待从机应答
IIC_Stop(); //iic停止信号
}
/*
brief BH1570读光照强度原始数据
param None
return 读出的光照数据
**/
u16 BhReadData(void)
{
u16 buf;
IIC_Start(); //iic起始信号
IIC_Send_Byte(BHAddRead); //发送器件地址+读标志位
IIC_Wait_Ack(); //等待从机应答
buf=IIC_Read_Byte(1); //读取数据
buf=buf<<8; //读取并保存高八位数据
buf+=IIC_Read_Byte(0); //读取并保存第八位数据
IIC_Stop(); //发送停止信号
return buf;
}
/*
brief BH1570连续读光照强度原始数据
param mode单次读的模式
return 读出的光照数据
注意:需要根据设置的读模式来延时获取数据
**/
u16 BhRead()
{
u16 LightIntensity=0;
LightIntensity=BhReadData();
LightIntensity=(int)(LightIntensity/1.2+0.5);
return LightIntensity;
}
/*
brief BH1570单次读光照强度原始数据
param mode单次读的模式
return 读出的光照数据
注意:需要根据设置的读模式来延时获取数据
**/
u16 BhSigRead(u8 mode)
{
u16 LightIntensity=0;
BhSendCommand(mode);
LightIntensity=BhReadData();
LightIntensity=(int)(LightIntensity/1.2+0.5);
return LightIntensity;
}
在这里我介绍下这几个函数:
void BH1570_Init(u8 mode); //BH1570初始化函数
u8 CheckBh(void);;//BH1570; //BH1570检测函数
u16 BhSigRead(u8 mode); //BH1570单次读
u16 BhRead(void); //BH1570连续读
BH1570_Init(u8 mode)是BH1570初始化函数,mode的选择值为:连续读(BHModeH1/BHModeH2/BHModeL) ,单次读(BHSigModeH/BHSigModeH2/BHSigModeL)。当我们需要单次读时在函数中调用BhSigRead(u8 mode)函数,当我们需要连续读时调用BhRead()这个函数,是不是简单方便。
测量效果
测试的单片机为STM32F103C8T6,SCL引脚PB3,SDA引脚PB4,程序通过串口1发送到PC。我先用手把传感器遮住然后再松开效果如图3所示,所处的环境是下午三点室内。对于IIC的驱动大家可以到我其他博客上面复制或者下载我上传的程序,上传的程序我没设置的下载卷为0,大家可以直接下载,创作不易,也希望大家忙里偷闲点个关注啥的。