【保姆级教程】STK3332系列环境光传感器整理!STK333X

      Hi,大家好我又回来了!这次整理了STK3332环境光与接近感应传感器,与STK3331相差不大,几乎可以替换使用,主要是STK3332比较好买。废话不多说,依然是从以下几点介绍,请大家耐心看完。

目录

1 简介

2 原理说明

2.1 光照度介绍

2.2 环境光

2.3 光电式接近感应

3 特性描述

3.1 电气特性

3.2 环境光传感器ALS特性

3.3 接近传感器PS特性

4 使用说明

4.1 模块初始化

4.2 数据处理

4.2.1 数据格式

4.2.2 测试数据


1 简介

        BMS33M332模块集成环境光传感器与接近传感器于一体。环境光传感器(ALS)可以感知周围光线的情况,此类传感器在手机、笔记本等电子产品中应用较为成熟,比如自动调节显示器背光亮度,可以大大降低功耗并且提高画面的可视性。其量程大约为0~65535 lux。

      接近传感器(PS)是感一种具有感知物体接近能力的器件。通过对IRLED发射光线的接近物产生的反射光,检测出人及物体的接近。一般用于感应设备,如感应水龙头、挥手感应等。感应的范围大约为20~25cm。

2 原理说明

2.1 光照度介绍

光照度,可简称照度,其计量单位的名称为“勒克斯”,简称“勒”,单位符号为“lux”,也可写为“lx”表示被摄主体表面单位面积上受到的光通量。1勒克斯等于1流明/平方米,即被摄主体每平方米的面积上,受距离一米、发光强度为1坎德垃的光源,垂直照射的光通量。光照度是衡量拍摄环境的一个重要指标。以下为各种常见环境的照度值(单位:lux):

  1. 晴天室外:30000~130000
  2. 晴天室内:100~1000
  3. 阴天室外:50~500
  4. 阴天室内:5~50
  5. 办公室:300~500
  6. 室内日光灯:100

阅读数所需要的照度:50~60

2.2 环境光

       环境光传感器它是可以模拟人眼对可见光的响应机制,如下图所示,人眼可见光的范围一般再390nm~750nm之间,峰值在555nm。通常ALS传感器都包含一个光电二极管或光敏晶体管管,然而,光电二极管或晶体管的光谱响应介于300nm到1100nm之间,而峰值落在700nm左右。一个可靠的环境光传感器,挑战在于要让它能和人眼一样,可以看见390nm~750nm的波长,但不能对300~390nm的紫外光和750nm~1100nm的红外光有反应。

图2-1

2.3 光电式接近感应

        接近传感器是由发射器(红外发射二极管IR)、接收器(光电二极管PD)和检测电路组成。如图2-2,将发射器与接收器按照一点的夹角放置,当有物体出现在传感器前方时,会将发射出的红外线反射至PD上,通过检测反射的IR能量与反射时间,即可判断前方是否有物体并且可以得到物体距离。

 图2-2

3 特性描述

3.1 电气特性

  1. VDD供电电压:3.3V~5V
  2. IR LED电压VLEDA :2.8V~4.6V
  3. 待机电流:1.36uA
  4. 工作环境温度:-40℃~85℃
  5. I2C时钟频率:400KHz

3.2 环境光传感器ALS特性

ALS单独工作电流:192uA~288uA

ALS峰值灵敏度波长:550nm

ALS满量程:65535counts(16-bitADC)

3.3 接近传感器PS特性

PS单独工作电流:208uA~312uA

高灵敏度波长范围:800nm~1000nm

PS满量程:65535counts(16-bitADC)

4 使用说明

4.1 模块初始化

1、使能相关的功能。需要根据实际情况使能相应的功能,如图4-1。

  • 寄存器地址:0X00—STATE
  • 写入数据  :0X0F, 使能PS、ALS、WAIT、NTELLI_PRST

 图4-1

2PS接近感应配置。对PS的积分时间、放大倍数以及触发中断的阈值倍数进行设定。

  • 寄存器地址:0X01—PSCTRL
  • 写入数据  :0X30, 积分时间为96uS,放大倍数为x 8,超出阈值1倍即触发中断

3ALS环境光感应配置。对ALS的积分时间、放大倍数以及触发中断的阈值倍数进行设定。

  • 寄存器地址:0X02—ALSCTRL1
  • 写入数据  :0X02, 积分时间为100mS,放大倍数为x 1,超出阈值1倍即触发中断

4、触发中断配置(可以忽略)设定触发模式。

  • 寄存器地址:0X04—INTCTRL1
  • 写入数据  :0X03,使能PS中断,选择PS_NF_MODE,如图4-2,当PS_ADC超过上限值THDH,INT_Pin输出持续为0,低于THDL,INT_Pin输出为1(视情况而定,本例只使能PS中断)。

图4-2 

5、设定阈值(中断使能后才有用)设定触发中断的阈值。

  • 寄存器地址:0X06~0X09—THDH_PS、THDL_PS(PS中断)
  • 写入数据  :THDH_PS = 7000,THDL_PS = 3000(视情况而定)

       在以上模块初始化的过程中,第四和第五需视情况而定,本例只设定了PS中断的触发,也可以根据实际情况不使能中断触发或者使能ALS中断

4.2 数据处理

4.2.1 数据格式

我们感兴趣的数据位于0X11到0X14这4个字节的寄存器当中。这些数据会自动更新,下面是相关的寄存器地址与数据名称。注意每个数据都是2个字节,高位在前低位在后。

  1. 0X11 0X12PS接近传感器输出的AD
  2. 0X13 0X14ALS环境光传感器输出的AD

4.2.2 测试数据

  • PS测试数据:

如图4-3所示的是PS count 与距离之间的曲线图,遮挡物体为不透明的立方体硬纸盒。其中模块PS_Gain = 8x,PS_Integration_Time = 96uS。

图4-3

      可以大致观察到,物理量距离与AD值之间呈非线性关系,并且在小于10cm时,AD值变化较为明显。  

  • ALS测试数据:

如图4-4所示的是ALS count 与物理量光照度之间的曲线图,其中光照度的值以专用照度计为参考,将专用照度计与模块放在同一环境下,记录照度计的值与模块的输出AD值。其中模块ALS_Gain = 1x,ALS_Integration_Time = 100mS。

图4-4 

        可以大致观察到,光照度与模块输出AD值线性相关,并且当模块ALS_Gain = 1x时,输出的AD值与光照度相差不大,即输出值即为光照度,如果需要更加的精确,还要去除offset的影响。

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
以下是一个示例的ls_stk3332.c驱动程序,用于实现RK3588与STK3332之间的音频输入和输出功能: ``` #include <linux/module.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/slab.h> #include <linux/regmap.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/control.h> #define STK3332_REG_GAIN 0x00 #define STK3332_REG_VOLUME 0x01 #define STK3332_REG_MUTE 0x02 struct stk3332_data { struct regmap *regmap; unsigned int gain; unsigned int volume; bool mute; }; static int stk3332_set_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct stk3332_data *data = snd_kcontrol_chip(kcontrol); unsigned int gain = ucontrol->value.integer.value[0]; if (gain > 255) gain = 255; data->gain = gain; regmap_write(data->regmap, STK3332_REG_GAIN, gain); return 0; } static int stk3332_get_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct stk3332_data *data = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = data->gain; return 0; } static int stk3332_set_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct stk3332_data *data = snd_kcontrol_chip(kcontrol); unsigned int volume = ucontrol->value.integer.value[0]; if (volume > 255) volume = 255; data->volume = volume; regmap_write(data->regmap, STK3332_REG_VOLUME, volume); return 0; } static int stk3332_get_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct stk3332_data *data = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = data->volume; return 0; } static int stk3332_set_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct stk3332_data *data = snd_kcontrol_chip(kcontrol); bool mute = ucontrol->value.integer.value[0]; data->mute = mute; regmap_write(data->regmap, STK3332_REG_MUTE, mute ? 1 : 0); return 0; } static int stk3332_get_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct stk3332_data *data = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = data->mute ? 1 : 0; return 0; } static const struct snd_kcontrol_new stk3332_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Gain", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .info = snd_ctl_boolean_mono_info, .get = stk3332_get_gain, .put = stk3332_set_gain, }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Volume", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .info = snd_ctl_boolean_mono_info, .get = stk3332_get_volume, .put = stk3332_set_volume, }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Mute", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .info = snd_ctl_boolean_mono_info, .get = stk3332_get_mute, .put = stk3332_set_mute, }, { } /* end */ }; static int stk3332_pcm_open(struct snd_pcm_substream *substream) { return 0; } static int stk3332_pcm_close(struct snd_pcm_substream *substream) { return 0; } static int stk3332_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { return 0; } static int stk3332_pcm_hw_free(struct snd_pcm_substream *substream) { return 0; } static struct snd_pcm_ops stk3332_pcm_ops = { .open = stk3332_pcm_open, .close = stk3332_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = stk3332_pcm_hw_params, .hw_free = stk3332_pcm_hw_free, }; static int stk3332_pcm_new(struct snd_card *card, struct snd_soc_pcm_runtime *rtd) { struct snd_pcm *pcm; int ret; ret = snd_pcm_new(card, "STK3332 PCM", 0, 1, 0, &pcm); if (ret < 0) return ret; pcm->private_data = rtd; pcm->info_flags = 0; strcpy(pcm->name, "STK3332 PCM"); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &stk3332_pcm_ops); return 0; } static int stk3332_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct stk3332_data *data; struct regmap *regmap; regmap = dev_get_regmap(dev->parent, NULL); if (!regmap) { dev_err(dev, "Failed to get regmap\n"); return -ENODEV; } data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->regmap = regmap; data->gain = 128; data->volume = 128; data->mute = false; platform_set_drvdata(pdev, data); // 注册音频控制器 snd_soc_register_codec(&pdev->dev, &codec_stk3332, &stk3332_dai, 1); // 注册PCM设备 return snd_soc_new_pcm_runtime(&pdev->dev, &stk3332_pcm_dai, &stk3332_pcm_platform, 0); } static int stk3332_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); return 0; } static const struct of_device_id stk3332_of_match[] = { { .compatible = "st,stk3332", }, { }, }; MODULE_DEVICE_TABLE(of, stk3332_of_match); static struct platform_driver stk3332_driver = { .probe = stk3332_probe, .remove = stk3332_remove, .driver = { .name = "stk3332", .of_match_table = stk3332_of_match, }, }; module_platform_driver(stk3332_driver); MODULE_DESCRIPTION("STK3332 audio driver"); MODULE_AUTHOR("Your Name"); MODULE_LICENSE("GPL"); ``` 以上驱动程序仅供参考,具体的驱动程序要根据实际的硬件连接和应用需求进行调整和修改。同时,需要根据实际情况进行dts配置和驱动程序的加载,以实现音频输入和输出的功能。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@努力再努力

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

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

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

打赏作者

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

抵扣说明:

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

余额充值