VEML7700是一款高精度环境光数字16位分辨率传感器,采用微型透明6.8 mm x 2.35 mm x 3.0 mm封装。它包括一个高灵敏度的光电二极管,一个低噪声放大器,一个16位a /D转换器,并支持一个易于使用的12C总线通信接口。
I2C器件的驱动方式很简单,其读写时序也是典型的I2C读写时序。
VEML7700包含实际的6个16位命令代码,用于操作控制、参数设置和结果缓冲。所有寄存器都可通过l2C通信访问。内置I2C接口兼容I2C模式“标准”和“快速”:10khz至400khz。2C h电平范围为1.3 V ~ 3.6 V。详细信息请参考NXP的I2C规格。读写时序如下。
其从机地址只有7bit,即001 0000 = 0x10,而根据I2C总线通信方式,按照8bit为一个数据的传输,7bit从机地址之后的1个bit表示读写方向,总线地址0010 0000= 0x20用于写,0010 0001= 0x21用于读。
VEML7700有6个用户可访问的16位命令地址,具体为00h到06h (03h未定义/保留)。
这6个16位命令地址用于操作控制、参数设置和获取结果参数。所有寄存器都可以通过l2C通信访问。具体命令表如下所示:
具体寄存器描述如下:
命令0:可配置增益、积分时间、存储保护数字、中断使能、上电使能
命令1:配置照明度上限窗口值
命令2:配置照明度下限窗口值
命令3:工作模式配置及节电使能
命令4:光照度高分辨率输出值
命令5:白色通道输出值
命令6:中断状态标志
配置对应的命令,可获得不一样的分辨率,其量程也相对应得到调整控制,具体增益(lx/bit 即流明/位)和量程(0~120klx)如下表所示;
后面附上实际控制代码,为模拟i2c读写接口
#define VEML_SDA_PIN GPIO_Pin_12
#define VEML_SDA_SET_OUTPUT GPIOB_ModeCfg(VEML_SDA_PIN,GPIO_ModeOut_PP_5mA)
#define VEML_SDA_SET_INPUT GPIOB_ModeCfg(VEML_SDA_PIN,GPIO_ModeIN_PU)
#define VEML_SDA_H GPIOB_SetBits(VEML_SDA_PIN)
#define VEML_SDA_L GPIOB_ResetBits(VEML_SDA_PIN)
#define READ_VEML_SDA !!(GPIOB_ReadPortPin(VEML_SDA_PIN))
#define VEML_SCL_PIN GPIO_Pin_13
#define VEML_SCL_SET_OUTPUT GPIOB_ModeCfg(VEML_SCL_PIN,GPIO_ModeOut_PP_5mA)
#define VEML_SCL_H GPIOB_SetBits(VEML_SCL_PIN)
#define VEML_SCL_L GPIOB_ResetBits(VEML_SCL_PIN)
#define SlaveAddress_WR 0x20
#define SlaveAddress_RD 0x21
#define SlaveAddress 0x21 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改
//ALT ADDRESS引脚接地时地址为0x46,接电源时地址为0xB8
uint8_t BUF[8] = {0};
uint16_t dis_data; //变量
uint32_t dis_temp;
void VEML7700_i2c_port_init(void)
{
// GPIOB_ModeCfg(GPIO_Pin_13 | GPIO_Pin_12, GPIO_ModeIN_PU);
VEML_SDA_SET_INPUT;
VEML_SCL_SET_OUTPUT;
VEML_SCL_H;
}
/**************************************
起始信号
**************************************/
void VEML7700_Start()
{
VEML_SDA_SET_OUTPUT;
VEML_SDA_H;//SDA = 1; //拉高数据线
VEML_SCL_H;//SCL = 1; //拉高时钟线
DelayUs(5);//Delay5us(); //延时
VEML_SDA_L;//SDA = 0; //产生下降沿
DelayUs(5);//Delay5us(); //延时
VEML_SCL_L;//SCL = 0; //拉低时钟线
}
/**************************************
停止信号
**************************************/
void VEML7700_Stop()
{
VEML_SDA_SET_OUTPUT;
VEML_SDA_L;//SDA = 0; //拉低数据线
VEML_SCL_H;//SCL = 1; //拉高时钟线
DelayUs(5);//Delay5us(); //延时
VEML_SDA_H;//SDA = 1; //产生上升沿
DelayUs(5);//Delay5us(); //延时
}
/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void VEML7700_SendACK(uint8_t ack)
{
VEML_SDA_SET_OUTPUT;
if(ack == 1)
{
VEML_SDA_H;
}
else {
VEML_SDA_L;
}
// SDA = ack; //写应答信号
VEML_SCL_H;//SCL = 1; //拉高时钟线
DelayUs(5);//Delay5us(); //延时
VEML_SCL_L;//SCL = 0; //拉低时钟线
DelayUs(5);//Delay5us(); //延时
}
/**************************************
接收应答信号
**************************************/
uint8_t VEML7700_RecvACK()
{
uint8_t ack_rcv = 0;
VEML_SDA_SET_INPUT;
VEML_SCL_H;//SCL = 1; //拉高时钟线
DelayUs(5);//Delay5us(); //延时
ack_rcv = READ_VEML_SDA;//CY = SDA; //读应答信号
VEML_SCL_L;//SCL = 0; //拉低时钟线
DelayUs(5);//Delay5us(); //延时
return ack_rcv;
}
/**************************************
向IIC总线发送一个字节数据
**************************************/
void VEML7700_SendByte(uint8_t dat)
{
uint8_t i;
VEML_SDA_SET_OUTPUT;
for (i=0; i<8; i++) //8位计数器
{
if(dat & 0x80)
{
VEML_SDA_H;
}
else {
VEML_SDA_L;
}
dat <<= 1; //移出数据的最高位
// SDA = CY; //送数据口
VEML_SCL_H;//SCL = 1; //拉高时钟线
DelayUs(5);//Delay5us(); //延时
VEML_SCL_L;//SCL = 0; //拉低时钟线
DelayUs(5);//Delay5us(); //延时
}
VEML7700_RecvACK();
}
/**************************************
从IIC总线接收一个字节数据
**************************************/
uint8_t VEML7700_RecvByte()
{
uint8_t i;
uint8_t dat = 0;
VEML_SDA_SET_INPUT;
// SDA = 1; //使能内部上拉,准备读取数据,
for (i=0; i<8; i++) //8位计数器
{
dat <<= 1;
VEML_SCL_H;//SCL = 1; //拉高时钟线
DelayUs(5);//Delay5us(); //延时
dat |= READ_VEML_SDA; //读数据
VEML_SCL_L;//SCL = 0; //拉低时钟线
DelayUs(5);//Delay5us(); //延时
}
return dat;
}
void Write_VEML7700_CMD(uint8_t CMD,uint16_t config_info)
{
VEML7700_Start(); //起始信号
VEML7700_SendByte(SlaveAddress_WR); //发送设备地址+写信号
VEML7700_SendByte(CMD); //内部寄存器地址,
VEML7700_SendByte(config_info & 0xff);//low 8 bit
VEML7700_SendByte((config_info >> 8) & 0xff);//high 8 bit
VEML7700_Stop();
}
void Read_VEML7700_ALS_VAL(void)
{
uint8_t i;
VEML7700_Start(); //起始信号
VEML7700_SendByte(SlaveAddress_WR); //发送设备地址+读信号
VEML7700_SendByte(CMD_ALS_VAL);
VEML7700_Start();
VEML7700_SendByte(SlaveAddress_RD);
for (i=0; i<3; i++) //连续读取2个地址数据,存储中BUF
{
BUF[i] = VEML7700_RecvByte(); //BUF[0]存储0x32地址中的数据
if (i == 3)
{
VEML7700_SendACK(1); //最后一个数据需要回NOACK
}
else
{
VEML7700_SendACK(0); //回应ACK
}
}
VEML7700_Stop(); //停止信号
DelayMs(5);
}
uint8_t VEML7700_work_task(void)
{
static uint8_t ret = 0;
static uint8_t cnt = 6;
if(ret == 0)
{
ret = 1;
if(cnt == 6)//运行一次,需要配置不同量程时再修改调用
{
Write_VEML7700_CMD(CMD_ALS_CONF_0,0x1300); // gain = 1/8, ALS intergeration time = 25ms,protect num = 1,ALS interrupt disable,power on
Write_VEML7700_CMD(CMD_PWR_SAVING,0x00); //mode 1,power saving disable
}
}
else {
ret = 0;
Read_VEML7700_ALS_VAL();//连续读出数据,存储在BUF中
dis_data=BUF[1];//高位在前
dis_data=(dis_data<<8)+BUF[0];//合成数据,即光照数据
dis_temp = (uint32_t)((dis_data * 1152)/625);
cnt++;
if(cnt >= 5)
{
cnt = 0;
// PRINT("buf0:%d,buf1:%d,dis_temp:%d\n",BUF[0],BUF[1],dis_temp);
}
PRINT("buf0:%d,buf1:%d,dis_temp:%d\n",BUF[0],BUF[1],dis_temp);
}
return ret;
}