烟雾检测模块ADPD188BI介绍与应用(二)

**[烟雾检测模块ADPD188BI介绍与应用(一)]**

一、前言

本篇文章续接上次烟雾检测模块ADPD188BI的介绍与应用(一),内容偏重于编程应用和补充介绍。其中内容为个人理解且通过实测,但难免有纰漏或错误,欢迎大家一起讨论交流,诚恳期待大家批评指正。图片来源为ADI公司官网提供的ADPD188BI数据手册和其他测试手册说明,侵删。

二、ADPD188BI补充介绍
烟雾报警器通常分为电离式报警器和光电式报警器。

电离式报警器原理为通过导电室的导电率波动来检测空气中的烟雾,一般采用电离辐射源,当空气中存在烟雾时,离子室的电流会发生变化,以此来产生报警。光电式报警器使用光电探测器对某个角度发射光源,通过一定的结构对光进行遮挡,测量空气中的烟雾反射到光电二极管的光所引起的光电流大小来检测烟雾。

ADPD188BI作为光电式烟雾探测器,相较于其他烟雾探测器,优点在于低功耗(根据不同寄存器有所不同),正常工作温度(-45°C-+85°C)采用双波长蓝光(850nm),红外光(470nm),可以有效判别干扰源,减少误报率,并且双波长在一定程度上具有分辨常见不同烟雾的能力。
在这里插入图片描述
图为ADPD188BILED光反向散射示意图。

三、ADPD188BI功能框图与工作流

进行寄存器配置和编程应用首先需要了解其硬件结构和工作流流向。
在这里插入图片描述
在这里插入图片描述
正常工作模式和数据流
正常模式下,ADPD188BI遵循一个由状态机设置的特定模式。
此模式的对应数据流框图如图24所示。该模式按顺序说明如下:

  1. LED脉冲和样本。ADPD188BI向外部LED发出脉冲。光电
    二极管对反射光的响应由ADPD188BI测量。每个数据样本
    均从n个脉冲之和构建,其中n为用户配置值,介于1和255
    之间。
  2. 样本间平均。如果需要,逻辑可以求取n个样本的均值以产
    生输出数据,其中n为2的幂,范围是2到128。每N个样本
    产生的新输出数据保存到输出寄存器。
  3. 数据读取。主机处理器从数据寄存器或FIFO中读取转换
    结果。
  4. 重复。该序列有若干不同环路以支持不同类型的均值计算,
    而两个时隙在时间上相互衔接。
    在这里插入图片描述
    功能框图和数据流和硬件连接,硬件连接注意事项在上一篇有较为详细的介绍这里不再赘述了。

四、软件驱动
ADI官方提供了ADPD188BI的驱动程序,下面给大家贴出链接,大家可以自行学习和下载:https://wiki.analog.com/resources/tools-software/uc-drivers/adpd188
给大家贴一下ADPD188BI官方驱动函数的图(部分截图),应该是很详细的
在这里插入图片描述
五、寄存器配置
解决了硬件接线,驱动程序,下面最重要的应该就是寄存器配置了。ADPD188BI具有很多寄存器,可以配置不同的模式和参数适应不同的环境,因此官方数据手册并未给出寄存器的推荐值而只给了默认值,下面介绍需要配置的寄存器和配置顺序,寄存器值和配置都仅供参考,并无标准,可以按照寄存器说明自行配置参数,列出的仅为修改了默认值的寄存器。

首先需要开启时钟并强制器件进入编程模式

  1. 将CLK32K_EN位(寄存器0x4B的位7)置1以启动采样时钟(32 kHz时钟)。此时钟控制状态机。如果此时钟关闭,状态机将无法按照寄存器0x10的定义转换状态。
  2. 将0x1写入寄存器0x10以强制器件进入编程模式。步骤1和步骤2可以交换,但实际状态转换要到这两步完成后才会发生。
    在这里插入图片描述
    在这里插入图片描述
    3.修改寄存器0x11配置时隙A,B的FIFO数据格式,可选16位和32位和。
    在这里插入图片描述
    4.配置寄存器0x5F校准32MHZ时钟
    在这里插入图片描述
    5.配置寄存器0x15,0x12,0x14,设置采样频率和均值系数
    6.配置时隙A,B脉冲个数,脉冲时间,AFE积分时间,积分路径
    7.开启A,B时隙,配置驱动电流
    8.配置PD电压,TIA增益
    9.进行时钟时序设置,进入采样模式
    10.读取数据寄存器

由于需要配置寄存器较多,具体寄存器详解列表的图不再贴出,请读者自行查阅数据手册,数据手册及参考资料官网下载地址链接放在这里,大家可以自行下载学习:https://www.analog.com/en/products/adpd188bi.html#product-evaluationkit

下面给出我个人按照数据手册进行配置的例子,仅供参考,不能够保证完全正确,同时也不具有实用意义,欢迎大家指出错误。

0x0F,0x0001); 					//	软件复位 寄存器清零
0x01,0xC0FF);					//	FIFO中断配置 数据长度超出0x06位[13:8]时产生中断
0x02,0x0005); 					//	使能GPIO0引脚
0x06,0x0001);					//  设置FIFO长度阈值
0x10,0x0001);          			//  进入编程模式
0x11,0x31B9); 					//	设置时隙A,B的FIFO数据格式			32	位和
0x4F,0x2090); 					//	样本同步选择和GPIO管脚设置
0x5F,0x0000); 					//  时钟设置
	
0x12,0x0A00); 					//	设置采样频率为50Hz fSAMPLE=32KHz/(0x12[15:0]*4)
0x15,0x0220);						//	时隙A,B样本和/均值系数为4,抽取
0x14,0x0110); 					//	时隙A,B双脉冲配置
	
0x18,0x0000);           //  时隙A通道1 ADC失调
0x19,0x3FFF);           //  时隙A通道2 ADC失调
0x1A,0x3FFF);           //  时隙A通道3 ADC失调
0x1B,0x3FFF);           //  时隙A通道4 ADC失调
0x30,0x0320); 		    //	时隙A 3us LED pulse
0x31,0x040E); 			//	时隙A 4 pulses
0x39,0x22F0); 			//	时隙A 4us AFE
0x42,0x1C34); 			//	AFE配置 配置为1的缓冲器,正常积分器配置 1.27V 200KΩ
0x43,0xADA5);					//	模拟全路径模式
0x5E,0x0808); 					//	时隙A禁用悬空
0x16,0x3000);						//	No Dark Bits
0x17,0x0009); 					//	Chop -++-
	
0x1E,0x0000);           //  时隙B通道1 ADC失调
0x1F,0x3FFF);           //  时隙B通道2 ADC失调
0x20,0x3FFF);           //  时隙B通道3 ADC失调
0x21,0x3FFF);           //  时隙B通道3 ADC失调
0x35,0x0320); 					//	时隙B 3us LED pulse
0x36,0x040E);						//	时隙B 4 pulses
0x3B,0x22F0); 					//	时隙B 4us AFE
0x44,0x1C34);						//	AFE配置 配置为1的缓冲器,正常积分器配置 1.27V 200KΩ
0x45,0xADA5); 					//	模拟全路径模式
0x59,0x0808); 					//	时隙B禁用悬空
0x1C,0x3000); 					//	No Dark Bits
0x1D,0x0009);						//	Chop -++-
	
0x58,0x0544); 					//	时隙A,B控制
	
0x22,0x3536);           //  配置LEDx3驱动器  电流粗调 
0x23,0x3536);           //  配置LEDx1驱动器  电流粗调
0x24,0x1530);           //  配置LEDx2驱动器  电流粗调
0x25,0x630C);           //  配置LEDx驱动器   电流精调
0x34,0x0000); 					//	时隙A,B LED禁用
		
0x3C,0x31C6);           //  通道开关
0x3D,0x0000);						
0x54,0x0AA0); 					//	配置PD电压
0x55,0x0000); 					//	配置TIA增益
0x5A,0x0010); 					//	
	
0x4B,0x26A2); 					//	时钟时序设置
0x4C,0x0004); 					//
0x4D,0x0090);						// 
    
 0x10,0x2);              //   进入采样模式 

配置寄存器后可以执行循环读取寄存器数值,下面是寄存器列表
在这里插入图片描述
六、读取数据寄存器
无中断时序的寄存器读取方法如下:

  1. 对于要求访问的时隙,写入1到SLOTA_DATA_HOLD或SLOTB_DATA_HOLD(分别为寄存器0x5F的位1和位2,两个时隙均可访问)。此设置可防止样本更新。
  2. 根据需要读取寄存器。
  3. 写 入 0 到之前设置的 SLOTA_DATA_HOLD 或 SLOTB_DATA_HOLD位(分别为寄存器0x5F的位1和位2)。重新允许样本更新。
    因为在读操作发生的同时,新样本可能到达,这种方法可防止新样本部分覆盖正被读取的数据。
    在这里插入图片描述
    七、计算PTR值
    计算PTR值我个人并没有再网上找到比较准确的公式和计算程序,先贴出找到的资料供大家参考,如果有错误欢迎告知我。
    在这里插入图片描述
    下面这个为CN-0537参考设计版(EVAL-CN0537-ARDZ)设计说明手册给出的公式。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    按照上述给出的公式,个人编写了部分程序,但结果与官方给出的PTR值存在很大差异,欢迎大家指出问题。
double ADPD188_PTR_LED1(u32 data)	
{
	u16 Moudle_ID;
	u16 LED1_GAIN_COEFF;
	u16 LED1_INT_COEFF;
	double GAIN_CAL_LED1,I_LED1;
	double Gain,INTER,NOMINAL_SCALAR;
	
	double K,PTR_LED1;
	double A0=9.8976*pow(10,-1);
	double A1=-5.1448*pow(10,-3);
	double A2=2.0287*pow(10,-5);
	double A3=-2.9645*pow(10,-8);
	double I_PD,I_LED1_PK,R_PD,N_LED;
	double I_LED1_COURSE,I_LED1_FINE,I_LED1_SCALE;

	R_PD=0.26;
	I_LED1_COURSE=50.3+19.8*6;
	I_LED1_FINE=0.74+0.022*12;
	I_LED1_SCALE=0.1+0.9*1;
	I_LED1_PK=I_LED1_COURSE*I_LED1_FINE*I_LED1_SCALE;
	I_LED1=I_LED1_COURSE*I_LED1_FINE;
	
	ADPD188_Write(0x5F,0x1); 
	ADPD188_Write(0x57,0x7);
	Moudle_ID=ADPD188_Read(0x67);
	if(Moudle_ID==0x04)
	{
		Moudle_ID=ADPD188_Read(0x70);
		LED1_GAIN_COEFF=ADPD188_Read(0x71);
		LED1_GAIN_COEFF=LED1_GAIN_COEFF&0x00FF;
	    LED1_INT_COEFF=ADPD188_Read(0x73);
		LED1_INT_COEFF=LED1_INT_COEFF&0x00FF;
		if(Moudle_ID==31||Moudle_ID==32)
		{
			Gain=17*(LED1_GAIN_COEFF-112)/256+17;
			INTER=8*(LED1_INT_COEFF-128);
			NOMINAL_SCALAR=17*I_LED1+622;
			GAIN_CAL_LED1=(Gain*I_LED1+INTER)/NOMINAL_SCALAR;
		}
	}
	else
		GAIN_CAL_LED1=0x00;
	
	ADPD188_Write(0x57,0x0);
	ADPD188_Write(0x5F,0x0);
	
	I_PD=data*0.41*1/4;
	K=A0+A1*I_LED1+A2*pow(I_LED1,2)+A3*pow(I_LED1,3);
	N_LED=0.38*K*GAIN_CAL_LED1;
	PTR_LED1=I_PD/I_LED1_PK*1/R_PD*1/N_LED;
	return PTR_LED1;
}

double ADPD188_PTR_LED3(u32 data)	
{
	u16 Moudle_ID;
	u16 LED3_GAIN_COEFF;
	u16 LED3_INT_COEFF;
	double GAIN_CAL_LED3;
	double Gain,INTER,NOMINAL_SCALAR;
	double K,PTR_LED3,I_LED3;
	double I_PD,I_LED3_PK,R_PD,N_LED;
	double I_LED3_COURSE,I_LED3_FINE,I_LED3_SCALE;

	R_PD=0.41;
	I_LED3_COURSE=50.3+19.8*9;
	I_LED3_FINE=0.74+0.022*12;
	I_LED3_SCALE=0.1+0.9*1;
	I_LED3_PK=I_LED3_COURSE*I_LED3_FINE*I_LED3_SCALE;
	I_LED3=I_LED3_COURSE*I_LED3_FINE;
	
	ADPD188_Write(0x5F,0x1); 
	ADPD188_Write(0x57,0x7);
	Moudle_ID=ADPD188_Read(0x67);
	if(Moudle_ID==0x04)
	{
		Moudle_ID=ADPD188_Read(0x70);
	  LED3_GAIN_COEFF=ADPD188_Read(0x72);
		LED3_GAIN_COEFF=LED3_GAIN_COEFF&0x00FF;
	  LED3_INT_COEFF=ADPD188_Read(0x74);
		LED3_INT_COEFF=LED3_INT_COEFF&0x00FF;
		if(Moudle_ID==31||Moudle_ID==32)
		{
			Gain=34*(LED3_GAIN_COEFF-112)/256+34;
			INTER=5*(LED3_INT_COEFF-128);
			NOMINAL_SCALAR=34*I_LED3+128;
			GAIN_CAL_LED3=(Gain*I_LED3+INTER)/NOMINAL_SCALAR;
		}
	}
	else
		GAIN_CAL_LED3=0x00;
	ADPD188_Write(0x57,0x0);
	ADPD188_Write(0x5F,0x0);
	

	I_PD=data*0.41*1/4;
	K=1.0;
	N_LED=0.22*K*GAIN_CAL_LED3;
	PTR_LED3=I_PD/I_LED3_PK*1/R_PD*1/N_LED;
	return PTR_LED3;
}

如果有使用过ADPD188BI光学模块的志同道合的伙伴欢迎大家一起交流学习,本人小白一枚错误纰漏在所难免,劳烦指正。文中手册链接皆来自ADI官网,如有侵权请告知我删除。

猜你喜欢

转载自blog.csdn.net/m0_51294753/article/details/120872468