原创 IIC压力传感器控制与使用(上)

2020-6-4 21:35 2643 39 6 分类: 工业电子 文集: 日积月累
------TE

公司以往水表上都是用的模拟输出的压力传感器,压力传感器输出的电压经单片机上的AD转换后,按照对应公式确定压力值。最近客户招标要求使用IIC输出的压力传感器,按照领导要求,国产的国外的都找到了一款,进行调试对比,以确定最终设计方案.

国外的找到一款TE生产的M320014位压力数字输出及11位温度数字输出,零偏移为0.5%,精度(总误差带)1.5%

我拿到的样品具体型号是M32JM-00010B-020BG,这个根据M3200参数手册的第10页看到型号的定义,J表示IIC输出,M表示1m长线,000表示无缓存装置,1表示睡眠模式,0表示数字地址为0x28B表示G1/4螺纹,020B表示压力最大支持20barG表示测量值为表压。

Tips

绝对压力

相对完全真空测量(零压力)。

表压

绝对压力与当地大气压力的差值。

真空压力

相对当地大气压力测量。真空总是负值。

密封压力

相对任意设定的压力测量。

      根据M3200参数手册的第4页介绍,传感器引出的四根线分别是红色、黑色、白色及绿色。红色线接VCC,黑色线接GND,白色线为SCL线,绿色线为SDA线。在另一个名为“interface to digital modules”的文档中第1页介绍了外部电路的连接,与常规的IIC电路一样,外接电源并且与单片机供电,并将SCLSDA分别接到单片机的对应引脚上,并在SCL线和SDA线分别上拉4.7k电阻。M3200电压范围支持2.7V~5.0V,我所用的单片机需要3.3V供电,故传感器我也直接3.3V供电(3.3V供电下,实测正常非睡眠模式电流20mA,睡眠模式下电流16uA)

外部硬件电路搞通后,就要研究如何用单片机去控制压力传感器,并且去读取内部数据了,这就需要仔细阅读TE提供的“interface to digital modules”文档了。我认为如果有过IIC使用经验的话,直接从该文档的第三页开始看第1.6小节即可,这里讲的是有关命令集和数据传输顺序。(IIC的功能莫过于:主机发送起始信号+主机向总线上发送一个字节数据+等待从机应答+主机从总线上获取从机发来的一个字节数据+主机收到后应答或不应答+主机发送结束信号)


可以看到有四条指令,这四条指令都是由单片机充当主机,传感器充当从机,由主机向从机发送起始信号,由从机应答。

(1) I2C_Read_MR

该指令是由主机发送测量命令,从机接到该命令后开始一轮测量与计算(注意并不回复测量结果)。实现方式是先由主机发送起始信号Start,然后发送一个字节数据,该数据为从机的默认地址0x28和一位读写位,先将0x28左移一位,给读写位留出地方,变成0x50,由于指令上最后一位读写位为R,即读写位位1,则该字节合起来为0x51,主机发送完以字节数据后要等待从机的应答信号,用于确认从机收到命令。收到从机的应答信号后,主机发送停止信号Stop信号,结束该条命令。此时,从机开始进行一轮测量。

(2) I2C_Read_DF2

该指令为主机获取从机的两字节数据的功能,这两字节数据包括2bit用于表示数据状态,14bit用于表示压力输出数值。从指令图可以看出,主机发送Start信号后,再发出0x51(从机地址+R),等待从机应答,收到应答后,主机从总线上获取两字节数据的高8位,然后主机发送应答信号,告诉从机,我收到你发的数据了,请你继续发,然后从机就会继续发送低8位数据,主机只需要从总线上再获取低8位数据就可以直接发送Stop信号,结束该指令即可,主机不需要收到低八位数据后再应答了,因为主机发现自己要的两个字节数据已经够了。

我们接下来要对收到的这两字节数据进行处理,首先提取出来BIT15BIT14,这两位组合起来去表示状态位。00表示数据正常,10表示该测量数据以前被读取过,不是最新的数据了,11表示检查到故障。把BIT13BIT0组合起来,转换为十进制数,这是压力输出数值。注意,压力输出数字并不是压力值,需要根据压力输出数字去计算对应的压力值。具体可以参考M3200 Pressure Transducer文件中的第六页介绍。以下是我自己的推导原理公式。

压力当前输出数值D,是指当前压力传感器输出的数值(BIT13~BIT0);

压力输出最大数值Dmax,是指该压力传感器满量程时可以输出的最大数值(BIT13~BIT0),这个值在M3200 Pressure Transducer文件中的第三页中介绍到最大输出数值为15000,最小输出数值为1000。这个是官方给的参考值,我建议还是实际去测量下,满量程和无压力时对应的输出数值,要不然用推荐值代入公式后计算,误差太大。

压力输出最小数值Dmin,是指该压力传感器负载压力为0Pa时,对应的压力输出值。官方推荐值为1000,建议实际测量。

当前压力值P,是指当前的实际压力值,单位可以是PaKPa,或者MPa,这个根据具体项目确定,我这里定义单位为KPa

压力最大值Pmax,指该压力传感器的满量程值,该压力传感器最大值为20bar,即2MPa

压力最小值Pmin,指该压力传感器的量程最小值,一般是0KPa

          

上面这个公式就是将压力数值转换为压力值的公式,利用的是压力数值占比与压力占比相等的原理。将上述公式进行继续推导,就可以得到压力值的表达式。

带入Dmin=1000,Dmax=15000,Pmax=2000,Pmin=0,

可得,P=(D-1000)*2000/14000.

所以,我们在程序中将上公式录入,从传感器获得压力数值D时,代入带公式中就可以得到实际压力P的值。

(3) I2C_Read_DF3  &  (4) I2C_Read_DF4

之所以将获取指令34放在一起,是因为3其实单独用没有啥实际意义,因为3获取的数据相比2来将,只是多了个温度值的高八位,通过指令4才可以获得温度值的整个11位数据。传感器可以通过温度值去自动校对压力值,输出当前温度下的压力值,这个校准在压力传感器内部的芯片已经自动校准了,不需要我们根据输出值进行校准。这个输出的温度值对于一些即需要压力数据又需要温度数据的用户比较方便。温度输出值转换为实际温度值的方法和压力的转换方法类似,具体可以参考M3200 Pressure Transducer文件中第七页公式进行计算,在此不再分析。

故,一般需要获取压力压力值的项目,直接使用指令(2)I2C_Read_DF2获取当前的压力值即可。

压力传感器有sleep睡眠模式和update激活模式两种。这个是由压力传感器内部的EEROM中存储的模式状态位决定的。修改模式,需要进入指令模式,然后读写EEROM进行修改,由于TE没有详细资料对此进行介绍,进入睡眠模式的指令不确定就没法进行切换。但国产压力传感器对本部分进行了介绍,我会在下篇(国产篇)中介绍如何修改模式。

sleep模式下,传感器是睡着的,你要读取压力数据时,要先进行唤醒它,它会进行测量并计算出压力数值,存放到EEROM中等待你去读取。等你读取完,它就继续睡觉了,等待你下一次的唤醒。而update模式的压力传感器,它不睡觉,它以一定周期的频率去自己主动测量压力值,并计算后存放到EEROM中,不管你是否读取该数据,它都会以一定周期的频率去刷新数据。它刷新的频率也是由其内部的EEROM中存储的周期值决定的,但TE并没有对该部分描述如何去修改。一般来讲,你如果读取频率不是太快,你读到的数据都是最新的压力值。

区分sleep模式和update模式的一个重要途径是问商家,另一个就是通过万能表去测量电流大小,若是uA级别,就是sleep模式,若是mA级别,就是update模式。

我拿到的这个TE的样品是个update模式的,使用起来比较简单,就是我想获取压力值的时侯,就对压力传感器上电,然后按照指令(2)I2C_Read_DF2的时序,对其进行读取,获得压力数值后代入我上面推导的公式,然后转换成压力值,显示到外界屏幕上,再把压力传感器断电即可。

   程序控制部分,我建议使用模拟IIC去进行通讯,我试过用ST的硬件IIC去读取,发现能通讯成功的概率很低,这大概是FLP当年埋下的雷吧。这个模拟IIC的例程在网上都可以找到,在此不再啰嗦。以下程序,以读取四个字节为例,进行展示如何获取压力数据。

  1. //----------------------------------------------------------------------------//
  2. //压力传感器相关参数定义
  3. //----------------------------------------------------------------------------//
  4. #define Pressure_Address 0x28 //压力传感器默认地址
  5. //--------------------------------------------//
  6. //全局变量声明
  7. //--------------------------------------------//
  8. u8 Pressure_Data_Buf[4];
  9. //--------------------------------------------//
  10. //函数名称:I2C_Read_DF4
  11. //入口参数:无
  12. //出口参数:是否成功,ERROR为0
  13. //说 明:获取四字节数据
  14. //-------------------------------------------//
  15. ErrorStatus I2C_Read_DF4(void)
  16. {
  17. u8 Address,i;
  18. Address = Pressure_Address;
  19. Address = (Address << 1)+ 0x01; //0x01表示读
  20. IIC_Send_Start(); //发送起始信号
  21. if(0x00 == IIC_Send_Byte(Address)) //发送地址
  22. return ERROR;
  23. for(i=0; i<3; i++)
  24. {
  25. Pressure_Data_Buf[i] = IIC_Get_Byte(0); //非最后一字节数据,要ACK
  26. }
  27. Pressure_Data_Buf[3] = IIC_Get_Byte(1); //最后一字节数据,无ACK
  28. IIC_Send_Stop(); //发送结束信号
  29. return SUCCESS;
  30. }
  31. //获得压力传感器输出的4字节数据后,就要对数据进行转换,转换成压力值进行输出。
  32. //--------------------------------------------//
  33. //全局变量声明
  34. //--------------------------------------------//
  35. u8 Pressure_Data_Buf[4];
  36. float Pressure;
  37. //----------------------------------------------------------------------------//
  38. //压力传感器相关参数定义
  39. //----------------------------------------------------------------------------//
  40. #define D_min 1000.0 //压力输出最小数值
  41. #define D_max 15000.0 //压力输出最大数值
  42. #define P_min 0.0 //压力量程最小值KPa
  43. #define P_max 2000.0 //压力量程最大值KPa
  44. //--------------------------------------------//
  45. //函数名称:Pressure_Data_Handle
  46. //入口参数:无
  47. //出口参数:是否成功,ERROR为0
  48. //说 明:用于处理转换压力数据
  49. //-------------------------------------------//
  50. ErrorStatus Pressure_Data_Handle(void)
  51. {
  52. u16 temp; //临时变量
  53. if((Pressure_Data_Buf[0] & 0xC0) == 0x00) //判断最高两位,确定数据是否正常
  54. {
  55. temp = Pressure_Data_Buf[0] & 0x3F;
  56. temp = temp << 8;
  57. temp = Pressure_Data_Buf[1] + temp; //组合压力输出值
  58. Pressure = (((float) temp)-D_min) * (P_max-P_min) / (D_max -D_min)+P_min; //代入压力计算公式
  59. return SUCCESS;
  60. }
  61. else
  62. return ERROR;
  63. }

在使用时,调用一次Pressure_Data_Handle函数,若返回值为成功,则将全局变量Pressure以浮点数的形式输出,即可表示当前的压力值。获取温度值的方式与获取压力值的方式类似,在此不再体现。


作者: wilsin, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-3880669.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

给作者打赏,鼓励TA抓紧创作!

赞赏支持
点赞 39
赞赏0

文章评论1条评论)

登录后参与讨论

艾矽易 2020-6-10 18:42

学习了
相关推荐阅读
wilsin 2022-09-27 22:17
【技术笔记】物联网日常工作笔记
1.C语言中,一个函数只能有一个返回值,若需要通过函数对函数外多个变量进行修改时,就要引入输入量为指针。如,带进位的加法运算,输入量为被加数与加数,返回值为是否进位。输入量为数值时,只能向函数输入值,...
wilsin 2020-09-30 22:33
不断电如何测设备功耗
领导:“测测它的功耗,看看正常不?”我:“中。”领导:“千万别断电啊,断了电再重新上电,单片机就复位了,怕复位了这故障就不见了。”我:“中。”回答完领导的话,我往我自己座位上走,边走边在心里琢磨,“我...
wilsin 2020-06-20 22:09
低功耗设备如何测试与分析功耗
我先唠点: 本文用于记录低功耗设备开发时,如何利用示波器测试出单片机进入低功耗模式,被中断唤醒后,执行完任务便继续进入低功耗模式。根据测试出的波形,对单片机睡眠时长及唤醒时长进行分析,进而判断低功耗设...
wilsin 2020-02-14 10:59
IAR如何设置为VS code黑色主题
最近,用IAR开发项目较频繁。IAR默认的白色主题,很是费眼睛,写一天代码下来常常会眼干眼花。以前用MDK软件时,默认也是白色主题,但是在网上找到了网友修改过的黑色主题包,直接替换主题包即可。于是变尝...
wilsin 2020-01-02 19:32
物联网行业中的常用的专业术语
写在前面:本人目前从事NB物联网水表开发工作,在工作中会遇到一些有关物联网(尤其是NB物联网)方面的专业术语,本文用于记录总结物联网术语知识,后期会随时增加总结内容,便于后续自我查找及各位网友参考。1...
我要评论
1
39
1
2
3
4
5
6
7
8
9
0
关闭 热点推荐上一条 /3 下一条