光传感器和距离传感器max44000源代码执行过程分析

电子说

1.2w人已加入

描述

  本文主要是关于光传感器和距离传感器的相关介绍,并着重对光传感器和距离传感器max44000源代码执行过程进行了详尽的分析叙述。

  光传感器

  光传感器通常是指能敏感由紫外光到红外光的光能量,并将光能量转换成电信号的器件。

  

  光传感器是一种传感装置,主要由光敏元件组成,主要分为环境光传感器、红外光传感器、太阳光传感器、紫外光传感器四类,主要应用在改变车身电子应用和智能照明系统等领域。现代电测技术日趋成熟,由于具有精度高、便于微机相连实现自动实时处理等优点,已经广泛应用在电气量和非电气量的测量中。然而电测法容易受到干扰,在交流测量时,频率响应不够宽及对耐压、绝缘方面有一定要求,在激光技术迅速发展的今天,已经能够解决上述的问题。

  磁光效应传感器就是利用激光技术发展而成的高性能传感器。激光,是20世纪60年代初迅速发展起来的又一新技术,它的出现标志着人们掌握和利用光波进入了一个新的阶段。由于以往普通光源单色度低,故很多重要的应用受到限制,而激光的出现,使无线电技术和光学技术突飞猛进、相互渗透、相互补充。利用激光已经制成了许多传感器,解决了许多以前不能解决的技术难题,使它适用于煤矿、石油、天然气贮存等危险、易燃的场所。比如说用激光制成的光导纤维传感器,能测量原油喷射、石油大罐龟裂的情况参数。在实测地点,不必电源供电,这对于安全防爆措施要求很严格的石油化工设备群尤为适用,也可用来在大型钢铁厂的某些环节实现光学方法的遥测化学技术。磁光效应传感器的原理主要是利用光的偏振状态来实现传感器的功能。当一束偏振光通过介质时,若在光束传播方向存在着一个外磁场,那么光通过偏振面将旋转一个角度,这就是磁光效应。也就是可以通过旋转的角度来测量外加的磁场。在特定的试验装置下,偏转的角度和输出的光强成正比,通过输出光照射激光二极管LD,就可以获得数字化的光强,用来测量特定的物理量。

  简单原理

  自60年代末开始,RC Lecraw提出有关磁光效应的研究报告后,引起大家的重视。日本,苏联等国家均开展了研究,国内也有学者进行探索。磁光效应的传感器具有优良的电绝缘性能和抗干扰、频响宽、响应快、安全防爆等特性,因此对一些特殊场合电磁参数的测量,有独特的功效,尤其在电力系统中高压大电流的测量方面、更显示它潜在的优势。同时通过开发处理系统的软件和硬件,也可以实现电焊机和机器人控制系统的自动实时测量。在磁光效应传感器的使用中,最重要的是选择磁光介质和激光器,不同的器件在灵敏度、工作范围方面都有不同的能力。随着近几十年来的高性能激光器和新型的磁光介质的出现,磁光效应传感器的性能越来越强,应用也越来越广泛。

  磁光效应传感器做为一种特定用途的传感器,能够在特定的环境中发挥自己的功能,也是一种非常重要的工业传感器。在电子防盗探测器领域,被动红外探测器的应用非常广泛,因其价格低廉、技术性能稳定而受到广大用户和专业人士的欢迎。但随着入侵者的反侦测技术手段的提高,从而对探头的要求也越来越高,普通被动红外探头的局限性也越来越明显,这样,新一代的被动红外探头也应运而生。因为加拿大的PARADOX SUCURITY SYSTEMS LTD的枫叶牌探头采用了很多最新技术,使用也较为广泛。所以,下面就结合该产品的技术特性来阐述被动红外探头的最新技术。

  1、反射式光传感器的工作原理及特性

  反射式光传感器是靠探测人体发射的红外线而进行工作的。探头收集外界的红外辐射通过聚集到红外感应源上面。红外感应源通常采用热释电元件,这种元件在接收了红外辐射温度发生变化时就会向外释放电荷,检测处理后产生报警。

  1) 这种探头是以探测人体辐射为目标的。所以辐射敏感元件对波长为10UM左右的红外辐射必须敏感。

  2) 为了仅仅对人体的红外辐射敏感,在它的辐射照面通常覆盖有特殊的滤光片,使环境的干扰受到明显的控制作用。

  3) 被动红外探头,其传感器包含两个互相串联或并联的热释电元。而且制成的两个电极化方向正好相反,环境背景辐射对两个热释元件几乎具有相同的作用,使其产生释电效应相互抵消,于是探测器无信号输出。

  4) 一旦人侵入探测区域内,人体红外辐射通过部分镜面聚焦,并被热释电元接收,但是两片热释电元接收到的热量不同,热释电也不同,不能抵消,经信号处理而报警。

  5) 多视场的获得,一是多法线小镜面组成的反光聚焦,聚光到传感器上称之为反射式光学系统。另一种是透射式光学系统,是多面组合一起的透镜——菲尼尔透镜聚焦在红外传感器上。

  6) 这要指出的是被动红外的几束光表示有几个视场,并非被动红外发红外光,视场越多,控制越严密。

  被动红外探头的优缺点:

  优点:本身不发任何类型的辐射,器件功耗很小,隐蔽性好。 光传感器

  价格低廉。

  缺点:

  ◆容易受各种热源、光源干扰

  ◆被动红外穿透力差,人体的红外辐射容易被遮挡,不易被探头接收。

  ◆易受射频辐射的干扰。

  距离传感器

  距离传感器,又叫做位移传感器,是传感器的一种,用于感应其与某物体间的距离以完成预设的某种功能,得到了相当广泛的应用。主要产品有手机距离传感器、远距离测量传感器等,应用于智能皮带中。

  原理

  “飞行时间法”(flying time)是通过发射特别短的并测量此光脉冲从发射到被物体反射回来的时间,通过测时间间隔来计算与物体之间的距离。

  距离传感器根据其工作原理的不同可分为光学距离传感器、红外距离传感器、超声波距离传感器等多种。手机上使用的距离传感器大多是红外距离传感器,其具有一个红外线发射管和一个红外线接收管,当发射管发出的红外线被接收管接收到时,表明距离较近,需要关闭屏幕以免出现误操作现象,而当接收管接收不到发射管发射的红外线时,表明距离较远,无需关闭屏幕。其它类型距离传感器的工作原理也大同小异,也是通过某种物质的发射与接受来判断其距离的远近,其发射的物质可以是超声波,光脉冲等等 [1] 。

  应用

  距离传感器最广泛的应用就是手机了,市场上的智能手机都含有距离传感器,当使用者接通电话时,手机距离耳朵较近,此时容易出现误操作现象(如大笑时鼓起的脸蛋儿易挂断电话),因此就需要距离传感器及时对距离进行监视,当出现距离过近时自动关闭屏幕,以避免误操作现象的发生。此外,距离传感器还可多用于矿井深度的测量、飞机高度的检测、野外环境的探查等方面,随着科技的不断发展,在可穿戴设备中也有突出表现(如智能皮带) 。

  光传感器和距离传感器max44000源代码执行过程分析

  TMD27713T内部集成一个光传感器,一颗红外发射管和一颗红外接收极管。

  ALS环境光传感器,距离检测和红外灯在一个模块上,ALS:近似于人眼的反应,可编程积分时间,可编程的中断阀值,很高的灵敏度。距离检测:校准到100mm的精度,消除工厂校准,可编程的数字红外脉冲。可编程的电流源的红外灯,可编程的中断阀值,可编程的等待时间。带微光学透镜的装置为红外线能的发送和接收提供高能有效的能量,降低整体功耗。

  Detailed Description:光到数字的装置提供了片上光敏二极管,AD转换,时钟,累加器,缓存,校准,状态机和I2C接口。

  光传感器,根据光线强度输出模拟信号,按电压大小指示环境光线强度。配合LED驱动芯片,自动调整LCD的背光强度。光线传感器根据光线强度输出一个指示信号,然后经过放大器送出。

  Proximity Sensor是由一颗红外发射管和一颗红外接收极管组成。通电后,红外管发射的红外光由于没有遮挡物反射红外信号,红外接收管没有动作。当有遮挡物时,会反射红外光,接收管接收到信号后,红外管导通,发出中断信号给DBB。LC1810通过I2C接口控制Gsensor、ALS&PS、COMPASS、Gyroscope芯片,通过GPIO完成各芯片的中断处理。接近光检测器被配置好相关红外感知灵敏度,但红外LED反射收到时,接近光检测器内部光敏二极管产生对应强度的电流,并转化为相应的数字量,并产生中断给微控制器(LC1810),LC1810通过I2C得到相关数字信息,并通过检测内部算法得到最终“接近信息”。

  板子上的信息:

  /*ALS + PS*/tmd22713初始化时i2c_client的配置信息

  #if defined(CONFIG_LIGHT_PROXIMITY_TMD22713T)

  static structtaos_cfgcomip_i2c_tmd22713_info= {

  .calibrate_target = 300000,

  .als_time = 50,//200,

  .scale_factor = 1,

  .gain_trim = 512,

  .filter_history = 3,

  .filter_count = 1,

  .gain = 1,//2,

  .prox_threshold_hi = 500,//120,

  .prox_threshold_lo = 400,//80,

  .als_threshold_hi = 3000,

  .als_threshold_lo = 10,

  .prox_int_time = 0xee, /* 50ms */

  .prox_adc_time = 0xff,

  .prox_wait_time = 0xee,

  .prox_intr_filter = 0x11,//0x23,

  .prox_config = 0,

  .prox_pulse_cnt = 0x08,

  .prox_gain = 0x61,//0x62,

  .int_gpio = mfp_to_gpio(TMD22713T_INT_PIN),

  };

  #endif

  //TMD22713在板子上的I2C接口信息:

  static struct i2c_board_info comip_i2c1_board_info[] = {

  #if defined(CONFIG_LIGHT_PROXIMITY_TMD22713T)

  {

  .type = “tritonFN”,

  .addr = 0x39,

  .platform_data = &comip_i2c_tmd22713_info,

  },

  #endif

  #if defined(CONFIG_LIGHT_PROXIMITY_TAOS_TMD22713T)

  {

  .type = “tritonFN”,

  .addr = 0x39,

  },

  #endif

  ……。}

  代码位置:kernel\lc1810\drivers\misc\light_prox\Tmd22713.c

  DECLARE_WAIT_QUEUE_HEAD(waitqueue_read); //定义一个等待队列用于处理中断

  #define ALS_PROX_DEBUG

  static char pro_buf[4];

  static int mcount = 0;

  static char als_buf[4];

  static bool enable_irq_mask = (bool)0;

  // per-device data

  struct taos_data { //定义taos_data结构体

  struct i2c_client *client; //定义I2c_client表示用的实际设备

  struct taos_cfg *taos_cfg_data; //初始化的配置信息

  struct work_struct work; //定义一个work_struct结构体处理任务

  struct wake_lock taos_wake_lock; //定义一个锁

  struct semaphore update_lock; //定义一个信号量

  struct miscdevice light_dev; //定义一个misc的设备light_dev

  struct miscdevice prox_dev; //定义一个misc的设备prox_dev

  wait_queue_head_t light_event_wait; //定义一个光传感器的等待队列

  wait_queue_head_t proximity_event_wait; //定义一个距离传感器的等待队列

  int lux_state; //lux的状态?

  int light_event; //light的事件

  int light_poll_delay; //light轮询时间

  int prox_state; //prox的状态

  int prox_event; //prox的事件

  int prox_poll_delay; //prox的轮询时间

  int irq; //中断

  };

  程序执行时:

  1、 module_init(taos_init);调用taos_init

  2、 static int __init taos_init(void)调用 i2c_add_driver(&taos_driver)加载驱动;

  3、 驱动定义如下:

  static struct i2c_driver taos_driver = {

  .driver = {

  .owner = THIS_MODULE,

  .name = TAOS_DEVICE_NAME,

  },

  .suspend = taos_suspend,

  .resume = taos_resume,

  .id_table = taos_idtable,//用于I2C driver的probe函数调用

  .probe = taos_probe, /* bus-》match成功后调用 */

  .remove = __devexit_p(taos_remove),

  }

  I2C_driver对应一套驱动方法,主要成员是probe()、remove()、suspend()等。另外id_table是该驱动所支持的I2C设备的ID表。I2C_client对应于真实的物理设备,每个I2C设备都需要一个I2C_client来描述。I2C_driver与I2c_client的关系是一对多,一个I2C设备上可以支持多个同类型的I2c_client.

  I2C_client的信息在BSP板文件board-lc1810.c中通过i2c_borad_info填充。

  在I2C总线驱动i2c_bus_type的match()函数i2c_device_match()中,会调用i2c_match_id()函数匹配板文件中定义的ID和i2c_driver所支持的ID表。通过bus-》match()匹配成功后开始调用probe函数进行一系列初始化动作。

  4、 static int taos_probe(struct i2c_client *clientp, const struct i2c_device_id *idp)的执行过程。

  1)、读取chipID,检测是否正确。

  2)、为taos_data分配空间并利用memset清零。

  3)、使用函数wake_lock_init()新建wakelock,该函数设置锁的名字,类型,最后将新建的锁挂接到一个专门链接这些非锁状态的链表上

  4)、初始化taos_data中两个设备的轮询等待时间,获取client指针。

  5)、INIT_WORK(&(taos_datap-》work),taos_work_func);

  第一个参数是初始化的一个工作队列,第二个参数是对这个工作队列的处理函数。INIT_WORK()函数把这个队列和处理函数绑定。

  处理函数如下:

  static void taos_work_func(struct work_struct * work)

  {

  struct taos_data *taos_data = container_of(work, struct taos_data, work);

  wake_lock(&taos_datap-》taos_wake_lock);

  taos_get_data();

  /*《after read data done, taos will not clear interrupts self-motion》*/

  taos_interrupts_clear(taos_data);

  wake_unlock(&taos_datap-》taos_wake_lock);

  }利用锁互斥访问,通过taos_get_data()获取数据。Taos_get_data()通过I2C命令读取寄存器和当前的状态设置距离传感器prox的阀值或者设置光传感器als的阀值,通过taos_als_get_data()最终获取数据。

  6)、通过init_waitqueue_head()函数分别初始化light和prox的等待队列。

  7)、填充light_dev和prox_dev的结构体,然后通过misc_register()函数注册两个设备,分别是light设备和prox设备。

  8)、通过i2c_smbus_write_byte操作控制寄存器。Sensor powerdown for init。

  9)、ret = gpio_request(taos_datap-》taos_cfg_data-》int_gpio, “taos irq”);

  gpio_direction_input(taos_datap-》taos_cfg_data-》int_gpio);

  taos_datap-》irq =gpio_to_irq(taos_datap-》taos_cfg_data-》int_gpio);

  ret =request_irq(taos_datap-》irq,taos_irq_handler,

  IRQ_TYPE_EDGE_FALLING, “taos_irq”, taos_datap);

  其中request_irq()函数通过中断申请,得到中断后用中断处理函数taos_irq_handler()进行处理。中断函数如下:

  static irqreturn_t taos_irq_handler(int irq, void *dev_id)

  {

  disable_irq_nosync(taos_datap-》irq);

  schedule_work(&taos_datap-》work);

  enable_irq(taos_datap-》irq);

  return IRQ_HANDLED;

  }

  系统调用处理在等待队列中的work事件。

  其中:workqueue内核实现原理可以描述如下:

  在Workqueue机制中,提供了一个系统默认的workqueue队列——keventd_wq,这个队列是Linux系统在初始化的时候就创建的。用户可以直接初始化一个work_struct对象,然后在该队列中进行调度,使用更加方便。

  Workqueue编程接口序号接口函数说明:

  a、 create_workqueue 用于创建一个workqueue队列,为系统中的每个CPU都创建一个内核线程。

  输入参数:@name:workqueue的名称

  b、 create_singlethread_workqueue 用于创建workqueue,只创建一个内核线程。输入参数:@name:workqueue名称

  c、 destroy_workqueue 释放workqueue队列。输入参数:@ workqueue_struct:需要释放的workqueue队列指针

  d、 schedule_work 调度执行一个具体的任务,执行的任务将会被挂入Linux系统提供的workqueue——keventd_wq输入参数:@ work_struct:具体任务对象指针

  e、 schedule_delayed_work 延迟一定时间去执行一个具体的任务,功能与schedule_work类似,多了一个延迟时间,输入参数:@work_struct:具体任务对象指针@delay:延迟时间

  f、 queue_work 调度执行一个指定workqueue中的任务。输入参数:@ workqueue_struct:指定的workqueue指针@work_struct:具体任务对象指针

  g、 queue_delayed_work 延迟调度执行一个指定workqueue中的任务,功能与queue_work类似,输入参数多了一个delay。

  在进行系统调用处理时用的是轮询处理的方法,程序中分别为light和prox定义了两个file_operations,连接如下:

  const structfile_operations taos_light_fops = {

  .owner = THIS_MODULE,

  .read = light_read,

  .poll = light_poll,//轮询函数

  .unlocked_ioctl = light_ioctl,

  .open = light_open,

  .release = light_release,

  };

  const structfile_operations taos_prox_fops= {

  .owner = THIS_MODULE,

  .read = prox_read,

  .poll = prox_poll,//轮询函数

  .unlocked_ioctl = prox_ioctl,

  .open = prox_open,

  .release = prox_release,

  };

  Select()和poll()是与设备阻塞与非阻塞访问息息相关的,使用非阻塞I/O的应用程序通常会使用select和poll()系统调用查询是否可对设备进行无阻塞的访问。

  static unsigned intlight_poll(struct file *file, struct poll_table_struct *poll)

  {

  int mask = 0;

  struct taos_data *data = (struct taos_data*)file-》private_data;

  poll_wait(file, &data-》light_event_wait, poll);

  if (data-》light_event)

  mask |= POLLIN | POLLRDNORM;

  return mask;

  }

  //第一个参数是file结构体指针,第二个为轮询表指针

  static unsigned intprox_poll(struct file *file, struct poll_table_struct *poll)

  {

  int mask = 0;

  struct taos_data *data = (struct taos_data*)file-》private_data;

  poll_wait(file, &data-》proximity_event_wait, poll);

  if (data-》prox_event)

  mask |= POLLIN | POLLRDNORM;

  return mask;

  }

  Poll()第一个参数是file的结构体指针,第二个参数是轮询表指针。这个函数的两项工作:

  、对可能引起的设备文件状态变化的等待队列调用poll_wait()函数,将对应的等待队列添加到poll_table。

  ②、返回表示是否能对设备进行无阻塞的读写访问的掩码。

  Poll_wait()的工作是把当前的进程添加到wait参数指定的等待列表(poll_table)中。

  阻塞和非阻塞访问时I/O操作的两种不同的模式,阻塞在I/O操作暂时不可进行时会让进程睡眠,非阻塞则不然。在设备驱动中阻塞I/O一般基于等待队列来实现,等待队列可用于同步驱动中事件发生的先后顺序。使用非阻塞I/O的应用程序也可借助轮询函数来查询设备是否能立即被访问,用户空间调用select()和poll()接口,设备驱动提供poll()函数。设备驱动的poll()本身不会阻塞,但是poll()和select()系统调用则会阻塞的等待文件描述集合中至少一个可访问或超时。

  结语

  关于光传感器和距离传感器的相关介绍就到这了,如有不足之处欢迎指正。

相关阅读推荐:重力感应器BMA250源代码执行分析

相关阅读推荐:详解接近传感器的主要功能及8大应用实例

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分