OPT3001光强传感器驱动实现(STM32F407)

上面是我的微信和QQ群,欢迎新朋友的加入。

写了个光强传感器的代码。

产品特点:
精密光学滤波以匹配人眼:拒绝IR> 99%(典型值)
自动满量程设定功能简化了软件,并确保正确的配置
0.01勒克斯至83K勒克斯
23位有效动态范围,自动增益范围
12二进制加权满量程范围设置:<0.2%(典型值)范围之间的匹配
低工作电流:1.8μA(典型值)
工作温度范围:-40°C至+ 85°C
宽电源电压范围:1.6 V至3.6 V
5.5-V容错I / O
PCB尺寸:14*13.5mm

OPT3001数字环境光传感器(ALS)高精度的人眼响应分线板
OPT3001是测量可见光的强度的传感器。传感器的光谱响应紧密匹配的人眼的明视响应并包括显着红外线排斥。
所述OPT3001是一个单芯片照度计,由人眼测量光作为??可见光的强度。精密光谱响应和强大的红外抑制装置的使OPT3001精确计人眼所看到不管光源的光的强度。强劲的IR抑制,也有助于保持高精确度时的工业设计为深色玻璃下安装传感器的美学要求。该OPT3001是专为创造人类基于光的经验系统,和理想的首选替代品光电二极管,光敏电阻,或者用更少的人眼匹配的IR抑制等环境光传感器。
测量可以从0.01勒克斯到83K勒克斯而不通过使用内置的,全面设置功能手动选择满量程范围进行。这个功能允许在一个23位的有效动态范围光测量。
数字操作灵活的系统集成。测量可以是连续的或单次。控制和中断系统具有自主运行,允许处理器睡觉而适当唤醒事件传感器搜索,通过中断引脚报告。
低功率消耗和OPT3001的低电源电压的能力提高电池供电系统的电池寿命。

模块是一个IIC驱动的传感器

这里提供底层IIC驱动源码

/*
功能:产生IIC起始信号
输入:无
输出:无
*/
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;  
	delay_us(5);
 	IIC_SDA=0;     //START:when CLK is high,DATA change form high to low 
	delay_us(5);
	IIC_SCL=0;     //钳住I2C总线,准备发送或接收数据 
}	  

/*
功能:产生IIC停止信号
输入:无
输出:无
*/
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	IIC_SCL=1;
	delay_us(5);
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us(5);
	IIC_SCL=0; 
	delay_us(5);						   					   	
}

/*
功能:等待应答信号到来
输入:1,接收应答失败
      0,接收应答成功
输出:无
*/
uint8_t IIC_Wait_Ack(void)
{
	uint8_t res=0;
	IIC_SDA=1;
	SDA_IN();      //SDA设置为输入  
	IIC_SCL=1;delay_us(5);	
  
	res = READ_SDA;
	delay_us(5);	
	IIC_SCL=0;//时钟输出0 	  
	
	return res;  
} 

/*
功能:产生ACK应答
输入:1,产生应答
      0,不产生应答
输出:无
*/
void IIC_Ack(uint8_t ack)
{
	SDA_OUT();
	IIC_SDA=ack;
	delay_us(5);
	IIC_SCL=1;
	delay_us(5);
	IIC_SCL=0;
}
		 				
/*
功能:IIC发送一个字节
输入:txd:发送数据
输出:无
*/
void IIC_Send_Byte(uint8_t txd)
{                        
	uint8_t t;   
	SDA_OUT(); 	    

	for(t=0;t<8;t++)
	{             
		if(txd&0x80)
			IIC_SDA=1;
		else 
			IIC_SDA=0;
			
			 
		delay_us(5);
		IIC_SCL=1;
		delay_us(5); 
		IIC_SCL=0;	
		delay_us(5);
		txd<<=1; 
	}	

	IIC_Wait_Ack();	
} 	    

/*
功能:IIC读取一个字节
输入:无
输出:返回数据
*/
uint8_t IIC_Read_Byte(void)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
	IIC_SDA=1;
    for(i=0;i<8;i++ )
	{
		receive <<= 1;
        IIC_SCL=1; 
        delay_us(5);
		receive |= READ_SDA;
		IIC_SCL=0; 
		delay_us(5);
    }					 
	
    return receive;
}

然后是阅读该传感器的数据手册

1、设备地址

从手册可知道,这个模块有四种地址配置

通过设置ADDR的连接,可以改变不同的设备地址

//定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改 拉低0x88  拉高0x8A  接SDA-0x8C 接SCL-0x8E

#define    SLAVEADDR    0x88

2、设备子地址

一共是6个地址,还蛮简单的,有一点要注意的是,这个芯片是16位的数据寄存器

3、只读寄存器

这是传感器数据保存的地址,要从传感器拿环境光强数据,就是在这拿,这个地方是只读的

4、配置寄存器

这是个十分重要的寄存器,不同的配置可能会导致读取的数据不一样

5、下限寄存器、上限寄存器

我没用到

6、ID寄存器

这个地方挺重要的

这个东西有两个ID:1.厂商ID 2.设备ID

为什么说他重要,可以通过读取ID,确定IIC驱动是否正常,如果这个ID读取不到,那后面的程序也没必要写下去了

从数据手册可以知道,设备厂商ID是0x5449,也就是ACSII码的"TI",设备ID是0x3001

7、初始化寄存器配置

上面就是芯片手册里面比较重要的寄存器的内容

现在根据配置寄存器的内容,实现芯片的配置,当然,这段配置我也是抄的,非专业我懒得去折腾

/*
功能:配置寄存器
输入:无
输出:无
*/
void opt3001_config(void)
{
	uint16_t vCfg = 0;
	
	//12:15 RN  	- 配置测量光照的范围 见手册20页表9  当配置位1100传感器测量范围自动选择
	//11    CT  	- 测量时间配置 0- 100Ms  1-800Ms
	//10:9  M[1:0]	- 转换模式 00-关闭模式  01 - 单次转换  10、11 - 连续多次转换
	//8     OVF     - 测量光照超出设定的范围或最大测量值 溢出标志
	//7     CRF		- 转换就绪字段 1-转换完成
	//6     FH		- 转换的光照值 大于上限值 置位
	//5     FL		- 转换的光照值 小于下限值 置位
	//4     L		- 中断输出的两种模式  1-窗口模式 这种模式下高限置位和低限置位INT输出  0-滞后模式 高限置位INT输出 具体看手册
	//3     POL		- INT 中断被触发输出极性 0-拉低  1-拉高
	//2     ME 		- 掩码字段
	//0:1   FC		- 超出上限范围故障计数  如果超出次数 大于等于计数设定次数  INT输出中断
	
	vCfg = (0x0C<<12);
	vCfg |= (0x01<<11);
	vCfg |= (0x01<<9);
	vCfg |= (0x01<<4);
	opt3001_write(REG_CONFIGURATION, vCfg);
}

8、实现ID的读取

/*
功能:读取厂商ID
输入:无
输出:无
*/
uint16_t ID=0;
void opt3001_manufacturer_id(void)
{
	ID = opt3001_read(REG_MANUFACTURER_ID);
}

/*
功能:读取设备ID
输入:无
输出:无
*/
void opt3001_device_id(void)
{
	ID = opt3001_read(REG_DEVICE_ID);
}

9、实现数据的获取

/*
功能:读取传感器数据
输入:无
输出:无
*/
#define ARRY_SIZE 10
uint32_t opt3001_data[ARRY_SIZE];
uint8_t arry_wpr=0;

uint8_t opt3001_get_lux(void)
{
	uint8_t		vRval 	= 0;
	uint16_t  	vCfg 	= 0;
	uint16_t  	vDat 	= 0;
	
	uint16_t  	vDatE = 0;
	uint16_t  	vDatR = 0;
	
	float   vFval 		= 0.0;
	float   vLsbSize 	= 0.0;
	float   vFlux 		= 0;
	
	vCfg = opt3001_read(REG_CONFIGURATION);
	vCfg |= (0x01<<9);
	opt3001_write(REG_CONFIGURATION, vCfg);		//单次采集光照
	
	vCfg = opt3001_read(REG_CONFIGURATION);
	delay_ms(900);								//大于800Ms
	
	vCfg = opt3001_read(REG_CONFIGURATION);
	if((vCfg&(0x01<<7)) )						//光照采集完成
	{
		vDat = opt3001_read(REG_RESULT);
		
		vDatE = ((vDat&0xF000)>>12);
		vDatR = (vDat&0x0FFF);
		
		vFval = (0x01<<vDatE);
		vLsbSize = (0.01f * vFval);
		
		vFlux  = (vLsbSize * (float)vDatR);
		opt3001_data[arry_wpr] = ((vFlux)*100.0f);//透明外壳不需要矫正 ,乳白色外壳推荐*1.8矫正 *vp_Lux = ((vFlux*1.8)*100.0)
		arry_wpr++;	
		if(arry_wpr >= ARRY_SIZE)		
		{
		arry_wpr = 0;
		}
	}
	else
	{
		vRval = 0x01;//光照采集失败
	}
	
	return vRval;
}

10、DEBUG看结果

首先检查厂商ID

然后查设备ID,可以看到,和数据手册是一致的

最后实现光强测试

可以看到数据会因为光强变化而变化

opt3001数字环境光传感器驱动实现包括以下步骤: 1. 初始化:首先需要初始化I2C总线,并设置适当的时钟、波特率以及传感器的I2C地址。然后通过I2C总线向传感器写入配置寄存器的值,包括采样率和其他参数的设定。 2. 数据读取:通过I2C总线向传感器的结果寄存器发送读取命令,并将读取的数据存储在适当的变量中。传感器的结果寄存器中包含了环境光的强度值,该值可以用于判断当前环境光的明暗程度。 3. 数据处理:将读取的环境光强度值进行相应的处理,例如转换成光强度的百分比或者亮度等级。根据不同的应用需求,可以使用适当的算法对数据进行处理,以满足特定的使用要求。 4. 数据输出:将处理后的环境光强度数据输出到外部设备或系统中,例如通过串口、SPI或其他通信接口发送到上位机或者其他外部设备进行显示或进一步处理。 5. 异常处理:在驱动实现的过程中,可能会发生一些异常情况,例如传感器通信异常、数据读取错误等。为了确保驱动的稳定性和可靠性,需要对这些异常情况进行处理,例如重新初始化传感器、进行错误提示或记录错误日志等。 总的来说,opt3001数字环境光传感器驱动实现需要通过I2C总线与传感器进行通信,并根据需要对传感器的配置进行设定,然后读取传感器的环境光强度数据并进行相应的处理和输出。通过合适的异常处理,可以提高驱动的稳定性和可靠性。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值