【瑞萨FPB_RA6E2】测评——光照传感器ISL29035数据读取
[复制链接]
本帖最后由 EPTmachine 于 2023-10-29 17:48 编辑
光照传感器ISL29035数据读取
ISL29035是瑞萨推出的一款自标定仿人眼的光照传感器,可用于检测环境中可见光强度。传感器的接口为I2C。本文使用fpb-ra6e2的I2C接口驱动ISL29035读取环境中光照数据。
RA6E2的I2C配置
产看数据手册可知,RA6E2的P410和P411引脚为I2C0的SCL和SDA引脚。
创建工程后,在FSP配置界面的Stack中添加I2C连接。
通过查看ISL29035的数据手册可知,其地址为0x44。
I2C接口的具体配置如下图所示
驱动I2C的函数主要有以下几个:
R_SCI_I2C_Open:打开I2C设备;
err = R_SCI_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);
R_SCI_I2C_Write:向I2C设备写入数据;
R_SCI_I2C_Write(&g_i2c0_ctrl, ii, 0x02, false);
R_SCI_I2C_Read:从I2C设备读取数据;
err = R_SCI_I2C_Read(&g_i2c0_ctrl, &value, 0x01, false);
sci_i2c_master_callback:中断回调函数,获取触发中断的事件,用于处理得到的数据。
void sci_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
/* TODO: add your own code here */
i2c_event = I2C_MASTER_EVENT_ABORTED;
if (NULL != p_args)
{
/* capture callback event for validating the i2c transfer event*/
i2c_event = p_args->event;
}
}
ISL29035初始化
ISL29035的上电初始化过程如下:
- 读取设备ID,查看是否链接上
- 清除标志位
- 确保芯片处于停止模式
- 设置分辨率
- 设置模式,如单次模式 读取设备ID使用0x0F指令,可以判断DEVICE ID BITS (B3-B5),之后需要对BROWNOUT STATUS BIT - BOUT (B7)清0。
与该操作相关的代码如下:
int DigitalLightISL29035_init(void) {
uint8_t reg = 0;
reg= DigitalLightISL29035_readRegister( CHIP_ID);//CHIP_ID->0x0f
//Serial.println(reg, HEX);
uint8_t chip_id = (reg >> 3) & 0x7;
if (chip_id != 0x5) {
return -1;
}
//清除BOUT位
DigitalLightISL29035_writeRegister(CHIP_ID, reg & 0x7f);//CHIP_ID->0x0f
//确保芯片处于停止模式
DigitalLightISL29035_writeRegister( COMMAND_I, 0);//COMMAND_I->0x00
//设置分辨率
DigitalLightISL29035_writeRegister(COMMAND_II, full_scale_lux_range | (integration_time << 2) );//COMMAND_2->0x01
//设置为单次模式
DigitalLightISL29035_writeRegister( COMMAND_I, OPMODE_ALS_ONCE);//COMMAND_I->0x00
return 0;
}
查看数据手册可知,ISL29035的写操作的方式如图
写寄存器的封装函数如下:
void DigitalLightISL29035_writeRegister( int reg_address, uint8_t val) {
uint16_t local_time_out = UINT16_MAX;
uint8_t ii[2]={0x00,0x00};
ii[0] = reg_address;
ii[1] = val;
err = R_SCI_I2C_Write(&g_i2c0_ctrl, ii, 0x02, false);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
//while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && local_time_out>0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
local_time_out--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
i2c_event = I2C_MASTER_EVENT_ABORTED;
}
ISL29035的读操作的方式如下:
读操作的函数封装如下:
uint8_t DigitalLightISL29035_readRegister(uint8_t reg_address) {
uint16_t local_time_out = UINT16_MAX;
uint8_t value;
err = R_SCI_I2C_Write(&g_i2c0_ctrl, ®_address, 0x01, false);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && local_time_out>0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
local_time_out--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
i2c_event = I2C_MASTER_EVENT_ABORTED;
local_time_out=UINT16_MAX;
/* Read data from I2C slave */
err = R_SCI_I2C_Read(&g_i2c0_ctrl, &value, 0x01, false);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_RX_COMPLETE != i2c_event) && local_time_out)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
local_time_out--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event)
{
__BKPT(0);
}
i2c_event = I2C_MASTER_EVENT_ABORTED;
return value;
}
操控传感器读取环境中的光照值,需要先设置操作模式寄存器的工作模式为0x010。进行一次光照采集。
在不同的ADC精度下,采样的时间不同,需要进行相应的延时操作。
完成采样后,可以从数据寄存器中读取去采集到的ADC采样值。
读取到原始数据后,可以根据手册中的计算公式进行计算。
相关的代码如下所示
uint32_t DigitalLightISL29035_readIRLux(void) {
uint16_t data = 0;
uint8_t l, h;
//设置为单次模式
DigitalLightISL29035_writeRegister( COMMAND_I, OPMODE_ALS_ONCE);
//等待时间
if(integration_time==0)
{
R_BSP_SoftwareDelay(105, BSP_DELAY_UNITS_MILLISECONDS);
}
else if(integration_time==1 || integration_time==2)
{
R_BSP_SoftwareDelay(7, BSP_DELAY_UNITS_MILLISECONDS);
}
else if(integration_time==3)
{
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
}
l=DigitalLightISL29035_readRegister(DATA_L);//DATA_L->0x02
h=DigitalLightISL29035_readRegister(DATA_H);//DATA_H->0x03
data=(h << 8) | l;
uint32_t ranges=0;
if(full_scale_lux_range==0)
ranges=1000;
else if(full_scale_lux_range==1)
ranges=4000;
else if(full_scale_lux_range==2)
ranges=16000;
else if(full_scale_lux_range==3)
ranges=64000;
uint32_t adc_count_max=0;
if(integration_time==0)
adc_count_max=65536;
else if(integration_time==1)
adc_count_max=4096;
else if(integration_time==2)
adc_count_max=256;
else if(integration_time==3)
adc_count_max=16;
return ranges * (uint32_t)data /adc_count_max;
}
在hal_entry.c中添加如下代码,可以从串口输出光照数据到PC。
void hal_entry(void)
{
/* TODO: add your own code here */
/* Open the transfer instance with initial configuration. */
err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
assert(FSP_SUCCESS == err);
/*Open the i2c port with initial configuration*/
err = R_SCI_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);
assert(FSP_SUCCESS == err);
printf("Hello World!\n");
DigitalLightISL29035_init();
R_BSP_SoftwareDelay(500U, BSP_DELAY_UNITS_MILLISECONDS);
lux = DigitalLightISL29035_readIRLux();
printf("lux=%d\n",lux);
while(1)
{
/*Delay 1 Second*/
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
lux = DigitalLightISL29035_readIRLux();
printf("lux=%d\n",lux);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
实际效果
连接开发板和ISL29035模块,运行程序后,在上位机打开串口调试工具,可以看到通过串口打印出来的光照值数据。
可以看到当前采集到的光照值,数值还是准确的。
总结
配合FSP配置工具,开发RA6E2的I2C应用程序是十分方便的,可以帮助开发者快速编写应用程序。
|