光感调试

我们使用手机时,经常会发现手机在不通环境下屏幕的背光亮度不一样。其实就是开启了自动背光调节功能。原理就是:光感获取环境光的值,然后背光根据一个环境光的曲线来调整背光的值。这个环境光曲线每家不一样,不同用户感知的效果也不一样。我们这里主要分享光感驱动部分。

下面以ISL29023 为例

1. 硬件连接

在这里插入图片描述
拿到规格书,第一步,确定管脚的描述定义,找到和主芯片通信的部分,电源相关PIN(VCC,GND), 中断,复杂的还需要时钟信号。在这里就是电源,中断以及IIC。

2.通信地址

硬件确认连接正常后,就需要确定通信的地址。该光感模组需要HW单独配置I2C地址,可以直接从datasheet 中获取。
在这里插入图片描述
在这里插入图片描述
在规格书,设备地址部分是一个8 bit 的地址,这里就是1000100左移1位即可。读写地址需要设备地址与最后一位做与操作,故读地址为 ((1000100 <<1) | 0x00 ) = 0x88 ,写地址为((1000100 <<1) | 0x01 ) = 0x89。

3.配置工作模式

在这里插入图片描述
command-I 寄存器对应有8种工作模式,通过B7~B5来配置其工作模式,此处我们选择101,另外B4,B3 保留为默认为0x00.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
table4,5 的中断参数全部置为0。 那么command-1 寄存器我们需要写入的值为:1010 0000 (0xA0).

而command-II 设置光控的最大阈值范围,ADC的有效取值位数
在这里插入图片描述
B0~B1 的值决定了光感最大的取值范围,这里我们B1B0 配置为0x01,那么范围是0 - 16000。
在这里插入图片描述
B3,B3 的取值分别对应的是ADC数据的有效位数是16,12,8,4位。此处我们设置为00,那么有效位是16位
在这里插入图片描述
那么,command-II 寄存器我们需要设置为 0000 0001 (0x01)

4. 读取数据

在这里插入图片描述
配置光感的工作模式后,就可以读取有效的数据值了。table-10 中,0x02,0x03 寄存器分别是低八位,高八位的数据。读出来之后,根据上一步配置来获取有效位。上一步配置为16 位,那么ADC值就应该是:
(reg[0x02] & 0xFF) | (reg[0x03] << 8 & 0xFF00)

5. 计算光感值

在这里插入图片描述
E 为最终光感值,由于前面我们配置的command-I 的B0,B1 是1,0 ,那对应的Range(K)就是Range3, 最大的光感值就是16000,而ADC的有效位是16位,那么2^16 也即为65536.

最终 E = ((reg[0x02]&0xFF) | (reg[0x03] << 8 & 0xFF00)) * 16000 / 65536

6.Code

void ISL29023_init(void)
{
	U8 data[2];
	memset(data,0,sizeof(data));
	mapi_i2c *iptr = mapi_i2c::GetI2C_Dev(ISL29023);  // 光感设备地址ID 

	data[0] = ISL29003_COMMAND_REG;  // reg: 0x00 ,也即 command-I 寄存器
	data[1] = ISL29003_CMD_DEFAULT;  // 0x00
	iptr->WriteBytes((MAPI_U8)1,  &data[0], (MAPI_U16)1, &data[1]);
	printf("[light_det][%s][%d] reg = %d  val = %d  \n",__FUNCTION__,__LINE__,data[0],data[1]);

	data[0] = ISL29003_COMMAND_REG; // reg: 0x00 ,也即 command-I 寄存器
	data[1] = 0xA0;                 // 1010 0000
	iptr->WriteBytes((MAPI_U8)1,  &data[0], (MAPI_U16)1, &data[1]);
	printf("[light_det][%s][%d] reg = %d  val = %d  \n",__FUNCTION__,__LINE__,data[0],data[1]);

	data[0] = ISL29003_CONTROL_REG;  // 0x01, 也即command-II寄存器
	data[1] = 0x01;                  // byte[0] = 1
	iptr->WriteBytes((MAPI_U8)1,  &data[0], (MAPI_U16)1, &data[1]);
	printf("[%s][%d] reg = %d  val = %d  \n",__FUNCTION__,__LINE__,data[0],data[1]);
}

首先,command-I 先写0x00,然后再写0xA0 完成初始状态到工作状态的配置。
接着,command-II写0x01, 设置光感的最大范围和ADC 数据的有效位数。

U32 GetLightSensorValue()
{
    ISL29023_init();
    U8 uLsbData[2];
    U8 uMsbData[2];
    memset(uLsbData,0,sizeof(uLsbData));
    memset(uMsbData,0,sizeof(uMsbData));
    U32 ambient_light;
    uLsbData[0] = ISL29003_DATA0_REG;  // reg:0x02  低八位数据寄存器
    uMsbData[0] = ISL29003_DATA1_REG;  // reg:0x03  低八位数据寄存器

    mapi_i2c *iptr = mapi_i2c::GetI2C_Dev(ISL29003); //  设备地址ID

    iptr->ReadBytes((MAPI_U8)1,  &uLsbData[0], (MAPI_U16)1, &uLsbData[1]);
	iptr->ReadBytes((MAPI_U8)1,  &uMsbData[0], (MAPI_U16)1, &uMsbData[1]);

	// E =  ((reg[0x02]&0xFF) | (reg[0x03] << 8 & 0xFF00))  * 16000 / 65536
    ambient_light = (uMsbData[1] << 8) | uLsbData[1];
    ambient_light = (ambient_light*16000)/65536;

    printf("[light_det][%s][%d] (ambient_light) = %d .\n",__FUNCTION__,__LINE__,ambient_light);

    return ambient_light;
}

读取0x02,0x03 的ADC值,计算得到光感的数据值。

7.自动调节背光

在这里插入图片描述
得到环境光的值,根据曲线自动调节背光。

发布了105 篇原创文章 · 获赞 20 · 访问量 34万+

猜你喜欢

转载自blog.csdn.net/kehyuanyu/article/details/104678548