光传感器OPT3001

        OPT3001是一款可如人眼般测量光强的单芯片照度计,测量范围0.01 lux-83k lux,使用IIC进行数据通信。它的引脚如下:

 它的应用框图如下:

         其中SCL,SDA为IIC通信脚,需接上拉电阻

         ADDR的接线影响IIC通信地址

        INT为中断输出,可设置光强阈值并通过该引脚触发警报

        芯片采用IIC通信,有关IIC通信原理可参考:

IIC通信原理-CSDN博客文章浏览阅读298次,点赞5次,收藏8次。这样看起来,区分起止信号与数据电平是不是就更加容易些了,但是嘛由于只有一根数据线了,缺点就是无法同时收发了,因此它是半双工通信的。一般的IIC器件,比如EEPROM,此时会发送要写入或读取的地址,如往0x0000地址写入数字1,那么会先发送0x0000,等到回码后再发送0x01,之后在收到应答后结束通信。前面在讲UART时提到过通信传输所需要的几个必要条件,首先得知道什么时候通信开始,什么时候通信结束,然后就是如何去解析数据了,根据这几点,我们来谈谈IIC是如何实现通信的。从图上可以看到,IIC规定的。https://blog.csdn.net/u011436603/article/details/136007075        光强的获取也很简单,只需要读取寄存器的值,再根据寄存器各位含义稍作转换一下即可,寄存器地址及各位的含义如下:

        更具体的各位的含义就得查阅手册了,不过如果只需要获取光强的话,可以直接参考下面的代码:

u16 OPT_ReadUserReg(u8 addr) //读寄存器   
{
    u8 lsb,msb;
    OPT_I2cStartCondition();                 
    OPT_I2cWriteByte(0x88);
    OPT_I2cWriteByte(addr);
	OPT_I2cStopCondition();
	
	OPT_I2cStartCondition();
	OPT_I2cWriteByte(0x89);
    msb = OPT_I2cReadByte();
	lsb=OPT_I2cReadByte();
    OPT_I2cStopCondition();
    return (msb<<8)|lsb;   
}

void OPT_WriteUserReg(u8 addr,u16 value) //写寄存器
{
    OPT_I2cStartCondition();
    OPT_I2cWriteByte(0x88);
    OPT_I2cWriteByte(addr);
	OPT_I2cWriteByte((u8)(value>>8));
	OPT_I2cWriteByte((u8)(value&0x00ff));
    OPT_I2cStopCondition();  
}
float OPT_ReadResult(void)
{
	u16 result;
    u16 exponent;
    u16 raw;
    raw = OPT_ReadUserReg(0x00);    //读result
    result = raw & 0x0fff;
    exponent = (raw & 0xf000) >> 12;
	return result * 0.01 *(2<<exponent);
}

float OPT_Measure(void)
{    
    OPT_SCL_OUTPUT();
    OPT_SDA_OUTPUT();
	OPT_WriteUserReg(0x01,0xcc10); //配置寄存器
	delay_ms(800);
	return OPT_ReadResult();//获取光强
}

         OPT_Measure函数即为最终的获取函数,在这个函数里首先对芯片进行了配置,然后调用OPT_ReadResult去获取光强。而OPT_ReadResult则是读取了0x01地址,即Result寄存器的值,然后再获取E[3:0]的值。

         再然后根据手册提供的公式获取到最终的目标值

         这里提供的例程仅仅是采集了光强值,并没有用到阈值报警等,因为获取到光强后就可以自己通过软件去设定阈值以及报警事件了,并不一定需要硬件来触发,当然感兴趣的也可以自行研究。

2024.7.19补充驱动时序函数(模拟方式)

void OPT_SCL_OUTPUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void OPT_SCL_INPUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void OPT_SDA_OUTPUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void OPT_SDA_INPUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}


void OPT_I2cStartCondition(void)
{
    OPT_SCL_OUTPUT();
    OPT_SDA_OUTPUT();
    
    OPT_SDA_HIGH();
    OPT_SCL_HIGH();
    delay_us(30);
		OPT_SDA_LOW(); 
    delay_us(30);
		OPT_SCL_LOW();
}
void OPT_I2cStopCondition(void)
{
    OPT_SCL_OUTPUT();
    OPT_SDA_OUTPUT();
    
    OPT_SDA_LOW();
    
    OPT_SCL_HIGH();
    delay_us(30);
    OPT_SDA_HIGH();
    delay_us(30);
		OPT_SCL_LOW();
}
void OPT_I2cAcknowledge(void)
{
    OPT_SCL_OUTPUT();
    OPT_SDA_OUTPUT();

    OPT_SDA_LOW();
    
    OPT_SCL_HIGH();
    delay_us(80);
    OPT_SCL_LOW();   
    delay_us(80);
}
void OPT_I2cNoAcknowledge(void)
{
    OPT_SCL_OUTPUT();
    OPT_SDA_OUTPUT();

    OPT_SDA_HIGH();
    
    OPT_SCL_HIGH();
    delay_us(80);
    OPT_SCL_LOW();   
    delay_us(80);
}

u8 OPT_I2cReadByte(void)
{
    u8 i, val = 0;

    OPT_SCL_OUTPUT();
    OPT_SDA_OUTPUT();

    OPT_SDA_HIGH();
    
    OPT_SDA_INPUT();
        
    for(i = 0; i < 8; i++)
    {
        val <<= 1; 
        
        OPT_SCL_HIGH();   
        
        if(Bit_SET == OPT_SDA_STATE()) 
        {
            val |= 0x01;
        }
        
        OPT_SCL_LOW();    
    }

    OPT_SDA_OUTPUT();

    OPT_SDA_HIGH();
    
    return (val);
}

u8 OPT_I2cWriteByte(u8 byte)
{
    u8 i, ack;

    OPT_SCL_OUTPUT();
    OPT_SDA_OUTPUT();
    
    for(i = 0; i < 8; i++)
    {
        if(byte & 0x80) 
        {
            OPT_SDA_HIGH();
        }
        else 
        {
            OPT_SDA_LOW();
        }
        
        OPT_SCL_HIGH();
        delay_us(80);
        OPT_SCL_LOW();   
        delay_us(80);
        
        byte <<= 1;
    }

    OPT_SDA_INPUT();
    
    OPT_SCL_HIGH();
    
    if(Bit_SET == OPT_SDA_STATE()) 
    {
        ack = ACK_ERROR;
    }
    else
    {
        ack = ACK_OK;
    }
    
    OPT_SCL_LOW();  

    OPT_SDA_OUTPUT();

    OPT_SDA_HIGH();
    
    return (ack);
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕诗客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值