流水源 发表于 2026-8-9 15:47:12

【瑞萨RA-eco-RA6M4评测】读取I2C接口光照接近传感器RPR-0521RS

本次学习读取I2C接口光照接近传感器RPR-0521RS的光照值和接近距离数据。

RPR-0521RS是将光学式接近传感器和红外LED(IrLED)、数字照度传感器整合在一起的传感器。 接近传感器 (PS)通过对IrLED发射光线的接近物产生的反射光,检测出人及物体的接近。另外,照度传感器(ALS)可测量从昏暗光线到直射日光的广泛照度。根据照度数据调整LCD显示器及按键的亮度,从而提高组件的节电性能和画面的可视性。

### RPR-0521RS系列光学传感器特点:

* 兼容I2C BUS接口(支持f/s模式); ·
* 兼容1.8V逻辑接口;
* 掉电模式下,电流损耗低;
* 有两种ALS输出值:可见光(Data0)对应光谱响应峰值;红外线光(Data1)对应光照度计算。
* 能检测到从黑暗环境乃至直接太阳光照的环境范围,具有广泛的照度测量;
* 具有抑制(工频)50Hz/60Hz光噪声(ALS功能下);
* 光学接近传感探测范围在1~100mm(可通过I2C接口调整);
* 内置电流配置的IrLED驱动器;

### 传感器和开发板连接如下:

传感器使用I2C引脚外设,电路图位置如下:
!(https://www.eefocus.com/forum/data/attachment/forum/202608/09/152828btg2jwmwnwjows4j.png)

硬件连接如下:

!(https://www.eefocus.com/forum/data/attachment/forum/202608/09/152737ykuujuyyf6lxhmwm.png)

接着添加RPR-0521RS驱动代码:

```
#include "drv_rpr0521rs.h"

#define   I2C_NUM   0
uint8_t   _als_data0_gain,_als_data1_gain;
uint16_t    _als_measure_time;

uint8_t RPR0521RS_Init(void)
{
    uint8_t   temp,index;

    uint8_t   als_gain_table[] = {1, 2, 64, 128};
    uint16_t    als_meas_time_table[] = {0,0,0,0,0,100,100,100,100,100,400,400,50,0,0,0};

    temp = I2C_ReadByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_MANUFACT_ID);
    if(temp != RPR0521RS_MANUFACT_ID_VAL)
    {
      return 1;
    }
    temp = I2C_ReadByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_SYSTEM_CONTROL);
    if((temp&0x3f) != RPR0521RS_PART_ID_VAL)
    {
      return 1;
    }

    I2C_WriteByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_ALS_PS_CONTROL, RPR0521RS_ALS_PS_CONTROL_VAL);

    temp = I2C_ReadByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_PS_CONTROL);
    temp |= RPR0521RS_PS_CONTROL_VAL;
    I2C_WriteByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_PS_CONTROL, temp);

    I2C_WriteByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_MODE_CONTROL, RPR0521RS_MODE_CONTROL_VAL);

    temp = RPR0521RS_ALS_PS_CONTROL_VAL;
    index = (temp >> 4) & 0x03;
    _als_data0_gain = als_gain_table;
    index = (temp >> 2) & 0x03;
    _als_data1_gain = als_gain_table;

    index = RPR0521RS_MODE_CONTROL_VAL & 0x0F;
    _als_measure_time = als_meas_time_table;

    return 0;
}



void RPR0521RS_get_rawdata(uint8_t *buff)
{
    I2C_PageRead(I2C_NUM, RPR0521RS_DEVICE_ADDRESS,
                RPR0521RS_PS_DATA_LSB,
                buff, 6);
}



float RPR0521RS_convert_lx(unsigned short *f)
{
    float lx;
    float d0, d1, d1_d0;

    if (_als_data0_gain == 0) {
      return (-1);
    }

    if (_als_data1_gain == 0) {
      return (-1);
    }

    if (_als_measure_time == 0)
    {
      return (-1);
    } else if (_als_measure_time == 50)
    {
      if ((f & 0x8000) == 0x8000)
      {
            f = 0x7FFF;
      }
      if ((f & 0x8000) == 0x8000)
      {
            f = 0x7FFF;
      }
    }

    d0 = (float)f * (100 / _als_measure_time) / _als_data0_gain;
    d1 = (float)f * (100 / _als_measure_time) / _als_data1_gain;

    if (d0 == 0) {
      lx = 0;
      return (lx);
    }

    d1_d0 = d1 / d0;

    if (d1_d0 < 0.595) {
      lx = (1.682 * d0 - 1.877 * d1);
    } else if (d1_d0 < 1.015) {
      lx = (0.644 * d0 - 0.132 * d1);
    } else if (d1_d0 < 1.352) {
      lx = (0.756 * d0 - 0.243 * d1);
    } else if (d1_d0 < 3.053) {
      lx = (0.766 * d0 - 0.25 * d1);
    } else {
      lx = 0;
    }

    return (lx);
}


void RPR0521RS_get_psalsval(unsigned int *ps, float *als)
{
    unsigned char val;
    unsigned short rawps;
    unsigned short rawals;

    RPR0521RS_get_rawdata(val);

    rawps   = ((unsigned short)val << 8) | val;
    rawals = ((unsigned short)val << 8) | val;
    rawals = ((unsigned short)val << 8) | val;

    *ps= rawps;
    *als = RPR0521RS_convert_lx(rawals);

}


uint8_t RPR0521RS_read_int(void)
{
    return I2C_ReadByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_INTERRUPT_CONTROL);
}

void RPR0521RS_write_int(uint8_t intvalue)
{
    I2C_WriteByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_INTERRUPT_CONTROL,intvalue);
}


void RPR0521RS_Set_PS_threshold(uint16_t ps_high,uint16_t ps_low)
{
    uint8_t buff;
    buff = ps_high&0xff;
    buff = (ps_high>>8)&0x0f;
    buff = ps_low&0xff;
    buff = (ps_low>>8)&0x0f;       
    I2C_PageWrite(I2C_NUM, RPR0521RS_DEVICE_ADDRESS,
                RPR0521RS_PS_TH_LSB,
                buff, 4);
}

void RPR0521RS_Set_ALS_threshold(uint16_t als_high,uint16_t als_low)
{
    uint8_t buff;
    buff = als_high&0xff;
    buff = (als_high>>8)&0xff;
    buff = als_low&0xff;
    buff = (als_low>>8)&0xff;
    I2C_PageWrite(I2C_NUM, RPR0521RS_DEVICE_ADDRESS,
                RPR0521RS_PS_TH_LSB,
                buff, 4);
}

void RPR0521RS_power_down(void)
{
    I2C_WriteByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_SYSTEM_CONTROL,0x80);
    I2C_WriteByte(I2C_NUM, RPR0521RS_DEVICE_ADDRESS, RPR0521RS_MODE_CONTROL,0);
}


#if UART_SHELL == 2
#include "nr_micro_shell.h"

void rpr0521rs_read(char argc, char *argv)
{
    unsigned int    ps;
    float         als;
   
    printf("rpr0521rs:%d\r\n",RPR0521RS_Init());
    RPR0521RS_get_psalsval(&ps, &als);
    printf("ps=%u,\t als=%f.\r\n",ps,als);
   
}

NR_SHELL_CMD_EXPORT(rpr0521,   rpr0521rs_read,   "get light senser rpr0521rs data");

#endif
```

接着就是在hal_entry.c中添加初始化传感器和读取数值并在oled上显示。
!(https://www.eefocus.com/forum/data/attachment/forum/202608/09/154642qs5c21hczerpirym.png)

最终效果如下:
!(https://www.eefocus.com/forum/data/attachment/forum/202608/09/154700u00u8cij2kjapjas.png)

!(https://www.eefocus.com/forum/data/attachment/forum/202608/09/154709wxiugujyz85b5bbu.png)



页: [1]
查看完整版本: 【瑞萨RA-eco-RA6M4评测】读取I2C接口光照接近传感器RPR-0521RS