COA3001介绍
COA3001是一种测量可见光强度的传感器。
传感器的光谱响应与人眼的光响应紧密匹配,并包括显著的红外抑制。
适用于有显示管理要求的智能手机、笔记本及相关智能设备。
COA3001的低功耗和低供电电压能力提高了电池供电系统的电池寿命。
寄存器介绍
对照手册来看,如果只是简单使用的话,仅仅需要用到0x00和0x01两个寄存器,分别是结果寄存器以及配置寄存器。从名字可以轻易看出,结果寄存器储存得到的结果,配置寄存器是配置相关设置,事实也是如此。
读写操作的设置:
本次使用的是IIC的方式,在手册中我们可以看到读写的流程:
芯片支持读、写操作的基本标准协议,
对于COA3001,所有寄存器数据都是16位,2字节格式。
读操作,主机先产生启动‘S’信号,然后发送用户设置的芯片从地址(RW位- 0),芯片通过拉低SDA确认从地址,然后主机发送寄存器地址,芯片确认。
主机将生成重新启动‘Sr’,然后再次发送从地址(RW位-1),芯片将再次ACK,首先输出16位(2字节)数据,然后是LSB,主机必须ACK MSB字节。
然后主机发送ACK或NACK,最后以“P”结尾。
简单来说就是
- 启动信号与从地址发送:
- 主机先产生启动‘S’信号。
- 然后发送用户设置的芯片从地址(RW位设为0,表示这是一个读操作)。
- 芯片通过拉低SDA(串行数据线)来确认接收到的从地址(等待应答)。
- 寄存器地址发送与确认:
- 主机在芯片确认从地址后,发送要读取的寄存器地址。
- 芯片再次通过拉低SDA来确认接收到的寄存器地址(等待应答)。
- 数据读取与确认:
- 主机生成重新启动‘Sr’信号。
- 然后再次发送从地址(RW位设为1,虽然在某些协议中这一步可能不是必须的,但根据描述进行划分),芯片再次通过拉低SDA进行ACK(应答)。
- 芯片首先输出16位(2字节)的数据,首先是MSB(最高有效位字节),然后是LSB(最低有效位字节)。
- 主机必须ACK(应答)MSB字节,表示已正确接收。
- 结束操作:
- 主机在接收完数据后,根据数据的正确性发送ACK(应答)或NACK(非应答)。
- 最后,以“P”信号来结束整个读操作
写操作,主机先产生启动S信号,然后发送用户设置的chinl的从机地址(RW位- 0),芯片通过拉低SDA确认从机地址,然后发送寄存器地址。芯片会识别。
主机将发送16位(2字节)的数据用MSB先写,然后LSB,传感器将逐字节ACK。
然后主机最后发出停止‘P’。
- 启动信号与从机地址发送:
- 主机首先产生启动信号‘S’,表示开始一次通信。
- 接着,主机发送用户设置的芯片(或称为从机)的地址,其中RW位设置为0,表示这是一个写操作。
- 芯片通过拉低SDA(串行数据线)来确认接收到的从机地址。
- 寄存器地址发送:
- 在确认从机地址后,主机发送要写入的寄存器地址。
- 芯片会识别并准备接收接下来的数据。
- 数据发送与逐字节ACK:
- 主机开始发送要写入的16位(2字节)数据。按照描述,首先是MSB(最高有效位字节),然后是LSB(最低有效位字节)。
- 芯片会逐字节地接收数据,并在每接收到一个字节后通过拉低SDA来发送ACK(应答),表示数据已正确接收。
- 停止信号:
- 在所有数据都成功发送并接收到ACK后,主机发出停止信号‘P’,表示写操作完成
代码部分:
使用普通的IIC代码即可。在.h文件中添加一些之前说到的各种寄存器
#define ADDR_x 0x88 //设备地址 地址引脚接地
#define result_x 0x00 //结果寄存器
#define COA3001_ConfigAdd 0x01 //操作寄存器
#define COA3001_Config_H 0xCC //1100 1100 固定值 800ms连续转换
#define COA3001_Config_L 0x10 //开启所存
.c中IIC的基础代码不过多介绍主要代码如下:
{
if(bit == ENABLE)
{
return ENABLE;
}
I2ccoaStart();
if(I2ccoaSendByte(ADDR_x))//没收到
{
I2ccoaStop();
return DISABLE;
}
if(I2ccoaSendByte(coa3001_ConfigAdd))//没收到
{
I2ccoaStop();
return DISABLE;
}
I2ccoaSendByte(coa3001_Config_H);//没收到
I2ccoaSendByte(coa3001_Config_L);//没收到
//I2ccoaStop();
bit = ENABLE;
delay_ms(800);
return ENABLE;
}
uint8_t High,Low;
float lux = 0;
float coa3001Readill(void)
{
//uint8_t High,Low;
uint16_t tmp = 0;
if(coa3001Writeill() == ENABLE)
{
//I2ccoaStart();
//delay_ms(800);
I2ccoaStart();
if(I2ccoaSendByte(ADDR_x))
{
I2ccoaStop();
return NULL;
}
if(I2ccoaSendByte(result_x))
{
I2ccoaStop();
return NULL;
}
I2ccoaStop();
I2ccoaStart();
if(I2ccoaSendByte(ADDR_x+1))
{
I2ccoaStop();
return NULL;
}
High = I2ccoaRecByte();
I2ccoaAck(1);
Low = I2ccoaRecByte();
I2ccoaAck(0);
I2ccoaStop();
uint8_t x = (High & 0xF0) >> 4; // 0xF0是11110000,右移4位得到前四位
uint8_t high_low_combined = (High & 0x0F) << 4 | (Low & 0xFF); // 0x0F是00001111,左移4位后与Low拼接
uint16_t y = (uint16_t)high_low_combined; // 转换为16位无符号整数
ill = 0.01 * pow(2, x) * y;
return ill;
}
}
最后即可得到取出来的值。