MPL115A 定点问题 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我想弄清楚我从压力传感器 MPL115A 收到的系数。我可以成功访问 IIC 总线并获取数据,但是 AN3785 中提供的算法似乎不起作用(至少对我来说是如此)。仔细研究这些评论,会发现一些问题。 例如,系数 C11 被描述为无 int 位和 10 frac 位的有符号数。 共有 11 个零。 因此,我认为这个数字看起来是这样的: S0.00000000000 F10 F9 F8 F7 F6 F5 F4 F3 F2 F1 F0 对我来说,这个数字的表示方法是 s(0,21),但注释却说是 s(16,27)。 当我从传感器中提取数据时,C11 显示为 0x0340。 这是一个 2 的补码,只使用前 11 位(10 个短语位和符号位)。 因此,如果我将其转换为实数(这并不是我在处理器中会做的事情,只是想看看我的理解是否正确),我将得到 S0.00000000000 0000 0011 010x xxxx 这将得到 2^-17+ 2^-18 + 2^-20 = 0.00001239776611328125 这是我的理解范围,我想知道是否有人能确认我的操作是否正确。 此外,由于 AN3785 中的算法将所有内容都保留在定点中,我不知道 lt1(一个 32 位的值)如何分配给 C11 才能正确合理。 当我将 0x0340 赋值给 long 时,得到的结果是 lt1 0x00000340 = 0000 0000 0000 0000 0000 0011 010x xxxx ,所以你可以看到我没有按照位宽规范正确对齐。 以下是代码片段。 这些评论对我来说毫无意义,所以你能提供的任何澄清都将是最有帮助的 //******* 步骤 1 c11x1= c11 * Padc lt1 = (S32) sic11;//s (16,27) s (N, f+ZeroPad) 来自 s (11,10) +11ZeroPad = s (11,22) = > Left Justified = s (16,27)-谢谢比尔 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我用 68hc912b32 的旧汇编器编写了这个代码 请注意,每个系数都放在一个 32 位变量中。 我相信还有优化的余地。 .include "globals.s" .包括 "hc12.s" c12x2:.blkb 4 a1:.blkb 4 a1x1:.blkb 4 y1:.blkb 4 a2x2:.blkb 4 PComp32:.blkb 4 baro_fltr:.blkb 3 ;*************************************************************************************************************** 初始化并读取系数 movb #0b00000000,sp0br 将 spi 设置为 4 MHz 时钟 ibaro: bclr portb,#0b10000000 将 CS 设置为低电平 movb #$88,sp0dr 读取 a0 msb brclr sp0sr,#SPIF,. 等待 spi movb #0, sp0dr; 正在清除字节 brclr sp0sr,#SPIF,. 等待 spi ldaa sp0dr 获取 a0 msb movb #$8A,sp0dr 读取 a0 LSB brclr sp0sr,#SPIF,. 等待 spi movb #0, sp0dr; 正在清除字节 brclr sp0sr,#SPIF,. 等待 spi ldab sp0dr 获取 a0 LSB std barocoA0;保存巴罗系数 a0 movb #$8C,sp0dr 读取 b1 的 MSB brclr sp0sr,#SPIF,. 等待 spi movb #0, sp0dr; 正在清除字节 brclr sp0sr,#SPIF,. 等待 spi ldaa sp0dr 获取 b1 MSB movb #$8e,sp0dr 读取 b1 LSB brclr sp0sr,#SPIF,. 等待 spi movb #0, sp0dr; 正在清除字节 brclr sp0sr,#SPIF,. 等待 spi ldab sp0dr 获取 b1 LSB std baroCob1;保存巴罗系数 b 1 movb #$90,sp0dr 读取 b2 msb brclr sp0sr,#SPIF,. 等待 spi movb #0, sp0dr; 正在清除字节 brclr sp0sr,#SPIF,. 等待 spi ldaa sp0dr 获取 b2 msb movb #$92,sp0dr 读取 b2 LSB brclr sp0sr,#SPIF,. 等待 spi movb #0, sp0dr; 正在清除字节 brclr sp0sr,#SPIF,. 等待 spi ldab sp0dr 获取 b2 LSB std baroCOB2;保存巴罗系数 b 2 movb #$94,sp0dr 读取 c12 的 MSB brclr sp0sr,#SPIF,. 等待 spi movb #0, sp0dr; 正在清除字节 brclr sp0sr,#SPIF,. 等待 spi ldaa sp0dr 获取 c12 MSB movb #$96,sp0dr 读取 c12 LSB brclr sp0sr,#SPIF,. 等待 spi movb #0, sp0dr; 正在清除字节 brclr sp0sr,#SPIF,. 等待 spi ldab sp0dr 获取 c12 LSB movb #0, sp0dr; 额外的清除字节 brclr sp0sr,#SPIF,. 等待 spi bset portb,#0b10000000 设置 CS hi std barococ12;保存巴罗系数 c12 rts CompBaro:: 乳化 ;Y:D中的结果需要移位11位 或除以 2^11 即 2048。 ldx #2048; **** 待办事项或者可以进行 3 次移位然后从中间字节加载 来完成其他 8 个比特。 sty c12x2+2 仅保存为 16 位 **** ;/ * ADCA A1 保留符号位 ldd a1+2 获取低 16 位 或 PComp32 移位 1 位 ; 待办事项查看此文件以获得最佳分辨率 ldd pcomp32+1 ;获取中间字节 有效移动 8 位 ldx #16394; 1023... 二进制分数乘以 16 使用指数为 15 的 IRR 过滤器来消除噪音 subd AmbBaro 减去最后一个滤波后的巴罗值 psha 保存标志 addd baro_fltr+1 ;累加器加法 lsword std baro_fltr+1; 更新 字节 ; msbyte 差值 tfr b,d ;将标志扩展到 acca adca baro_fltr 将带进位的加法运算加到 msbyte 累加器 staa baro_fltr 更新 ldd baro_fltr 在 msword 中显示 IIR 滤波结果 pshd 到堆栈上的 temp ldab baro_fltr+2 ; 用于左移的 lsbyte 过滤器 ldaa #15 滤波器控制,0 = 最小滤波频率,15 = 最大滤波频率 递减时的翻转位? eora #$F 如果还不够,*** 可以使用 Higer 减少过滤 => 更多移位 bfc1: beq bfc2 开始移位循环以减少过滤 lslb 左移 lsbyte 1,s ;转变为过滤压力 滾動 毫字节 十进制 减去第 4 位的 dec 移位计数 bra bfc1 重复 bfc2: puld ; 检索结果 std ambBaro; 结果为 kpa= mbar* 10 杰克 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
谢谢你,托马斯、 我现在明白了。 Dave Re: Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
嗨,戴夫、 我刚才已经在你的 SR 1-1348149811 中解释过了。 首先,您需要考虑到 c12_LSB 的最后两位为零,如数据表第 5 页所示: c12 MSB 字节 = c12 [13:6] = [b13、b12、b11、b10、b9、b8、b7、b6] c12 LSB 字节 = c12 [5:0] & “00” = [b5、b4、b3、b2、b1、b0、0、0、0] 然后,c12 系数的格式如下: c12 = b13 0 .000 000 000 B12 B11 B10 B9 B8 B7 B6 B5 B4 B3 B2 B1 B0 因此,每个小数位的值为 1 / 2^(9+13),16 位的 c12 值需要先右移 2(或除以 4),才能得到 13 个小数位。 以我们的例子为例,16 位 c12 = 0x33C8。 那么 c12>> 2 = 0x33C8>> 2 = 0xCF2 = 3314 c12 系数 = 3314 / 2^22 = 0.00079 希望对您有所帮助。 此致, 托马斯 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
哦,对不起。 我看到 2 个 LSB 均为零。 但我还是不明白你是如何得到 0.000790 的。 d. Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
哎呀,我知道这个话题已经有好几年了。 但我很笨。 比尔的原帖是关于 c12 的,他说数据表显示有 11 个焊盘零。 我的数据表上写着 9 个垫零。 数据表中 c12 的值是 0x33C8,这让我一头雾水。 我不明白你是如何从这个数值得出 0.000790 的。 如果在 F12 - F0 之间填充 9 个 0,就会得到 0000000001001.... 这意味着前 1 位将是 2^^-10,或 0.0009xxx,已经大于 0.000790。 对不起,我不明白。 有人有什么想法吗? 谢谢! d. Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
要转换 c12 的系数吗? MSB c12 = 00110000 LSB c12 = 101011xx Coef c12 =S0, 000000000 00 110000101011xx = 2^-10 + 2^-11 + 2^-16 + 2^-18 + 2^-20 + 2^-21 = 0,001485 是这样吗? Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
嗨,妈妈、 你的问题解决了吗? 负压和 PADC 值 = 990 此致敬礼 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
彼得,请解释一下你是如何计算 C12 的。AN3785 说 dec pt zero pad=9。因此,9"0" 后" 。" 如果我这样做,就无法获得可接受的结果。甚至所有其他值都与你的几乎相同。 谢谢! Michael Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
新手,但愿意学习。感谢您提供的编码示例。您是否有原始数据和结果,以便我确定是否已正确转换为 VB?谢谢。 我用的是 Padc 64 C0 Tadc 75 80 A0 - 3D 9B B1 - B9 4A B2 - C7 46 公元前 12 - 32 年 C11 - 02 20 C22 - FD 60 我的结果是 105.13476438 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我正在尝试连接这个设备,但遇到了一些问题。我从设备上得到的系数和读数如下: a0:3b99 b1:ffffb8b9 b2:ffffc24d c12:3274 c11:0 c22:0 Padc:157 Tadc:1f5 Padc:343 Tadc:501 温度: 26.536017 摄氏度 压力: 51.450000 千帕 补偿压力: 91.935486 kPA 在论坛前面使用浮点系数函数我得到了这些值: A0_D:1906.250000 b1_d:-2.056824 b2_d:-0.240997 c12_d:0.000192 c11_d:0.000000 c22_d:0.000000 压力_d:120.723752 千帕 我将这些双数值提取出来,然后使用......来计算: Pcomp = a0_D + (b1_D + c11_D*Padc + c12_D*Tadc)*Padc + (b2_D + c22_D*Tadc)*Tadc 然后使用(65.0/1023.0*Pcomp+ 50,我得到压力_d。我需要做什么特别的事情吗?因为这两个数字都不符合我预计的 101 千帕,更让人困惑的是这些数字都不一样。第一个补偿压力值是根据应用笔记表计算的。 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
好了,我终于找到问题所在了。问题出在数据类型 int 上。我的意思是它有 16 位(如 gcc、borland c 等),但实际上它有 32 位。因此负数不是负数... 解决办法是将所有 int 改为 short(至少在 CW 6.3 中)。 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
HI 有谁解开了这个数学之谜?我终于可以读取传感器的数据了,但我无法通过应用程序中描述的数学运算。第 17-18 页的说明。作为 siPcomp,我得到了大约 5726,大大超过了 1023... 系数没有问题(处理为浮动,仅供参考: A0 结果 = 2101 B1 结果 = -2.4163818359375 B2 结果 = -1.2173461914062 C12 结果 = 0.00083708763122559 C11 结果 = 0 C22 结果 = 0 代码完全是从应用程序中复制粘贴的。注意,但结果却完全是疯狂的... 谁有可用的代码片段? 我的数据在这里(压力、温度、系数): 5B 40 81 80 41 A8 B2 AD B2 17 36 DC 00 00 00 00 我的代码在这里: unsigned char mpl115a_raw_data[16];unsigned int mpl115a_p;unsigned int mpl115a_t;signed int mpl115a_a0;signed int mpl115a_b1;signed int mpl115a_b2;signed int mpl115a_c12;signed int mpl115a_c11;signed int mpl115a_c22;//====================================================// MPL115A Placing Coefficients into 16 bit variables//====================================================void mpl115a_raw_dissection(void){ mpl115a_p = (unsigned int)mpl115a_raw_data[0] <<8; mpl115a_p += (unsigned int)mpl115a_raw_data[1] & 0x00FF; mpl115a_t = (unsigned int)mpl115a_raw_data[2] <<8; mpl115a_t += (unsigned int)mpl115a_raw_data[3] & 0x00FF; mpl115a_a0 = (signed int)mpl115a_raw_data[4] <<8; mpl115a_a0 += (signed int)mpl115a_raw_data[5] & 0x00FF; mpl115a_b1 = (signed int)mpl115a_raw_data[6] <<8; mpl115a_b1 += (signed int)mpl115a_raw_data[7] & 0x00FF; mpl115a_b2 = (signed int)mpl115a_raw_data[8] <<8; mpl115a_b2 += (signed int)mpl115a_raw_data[9] & 0x00FF; mpl115a_c12 = (signed int)mpl115a_raw_data[10] <<8; mpl115a_c12 += (signed int)mpl115a_raw_data[11] & 0x00FF; mpl115a_c11 = (signed int)mpl115a_raw_data[12] <<8; mpl115a_c11 += (signed int)mpl115a_raw_data[13] & 0x00FF; mpl115a_c22 = (signed int)mpl115a_raw_data[14] <<8; mpl115a_c22 += (signed int)mpl115a_raw_data[15] & 0x00FF;}//===================================================//Coefficient 9 equation compensation//===================================================unsigned long mpl115a_compensated_pressure(void){ //Variable used to do large calculation as 3 temp variables in the process below signed long lt1, lt2, lt3, si_c11x1, si_a11, si_c12x2, si_a1, si_c22x2, si_a2, si_a1x1, si_y1, si_a2x2;; //Variables used for Pressure and Temperature Raw. unsigned int uiPadc, uiTadc; signed int siPcomp; unsigned long decPcomp; uiPadc = mpl115a_p >> 6; uiTadc = mpl115a_t >> 6; //******* STEP 1 c11x1= c11 * Padc lt1 = (signed long) mpl115a_c11; lt2 = (signed long) uiPadc; lt3 = lt1 * lt2; si_c11x1 = (signed long) lt3; //******* STEP 2 a11= b1 + c11x1 lt1 = ((signed long) mpl115a_b1) << 14; lt2 = (signed long) si_c11x1; lt3 = lt1 + lt2; si_a11 = (signed long) (lt3 >> 14); //******* STEP 3 c12x2= c12 * Tadc lt1 = (signed long) mpl115a_c12; lt2 = (signed long) uiTadc; lt3 = lt1 * lt2; si_c12x2 = (signed long) lt3; //******* STEP 4 a1= a11 + c12x2 lt1 = ((signed long) si_a11) << 11; lt2 = (signed long) si_c12x2; lt3 = lt1 + lt2; si_a1 =(signed long) (lt3 >> 11); //******* STEP 5 c22x2= c22 * Tadc lt1 = (signed long) mpl115a_c22; lt2 = (signed long) uiTadc; lt3 = lt1 * lt2; si_c22x2 = (signed long) lt3; //******* STEP 6 a2= b2 + c22x2 lt1 = ((signed long) mpl115a_b2) << 15; lt2 = ((signed long) si_c22x2) >> 1; lt3 = lt1 + lt2; si_a2 = ((signed long)lt3) >> 16; //******* STEP 7 a1x1= a1 * Padc lt1 = (signed long) si_a1; lt2 = (signed long) uiPadc; lt3 = lt1 * lt2; si_a1x1 = (signed long) lt3; //******* STEP 8 y1= a0 + a1x1 lt1 = ((signed long) mpl115a_a0) << 10; lt2 = (signed long) si_a1x1; lt3 = lt1 + lt2; si_y1 = ((signed long)lt3) >> 10; //******* STEP 9 a2x2= a2 *Tadc lt1 = (signed long) si_a2; lt2 = (signed long) uiTadc; lt3 = lt1 * lt2; si_a2x2 = (signed long) lt3; //******* STEP 10 pComp = y1 +a2x2 lt1 = ((signed long) si_y1) << 10; lt2 = (signed long) si_a2x2; lt3 = lt1 + lt2; // FIXED POINT RESULT WITH ROUNDING: siPcomp = (signed int)(lt3 >> 13); // goes to no fractional parts since this is an ADC count. //decPcomp is defined as a floating point number. //Conversion to Decimal value from 1023 ADC count value. ADC counts are 0 to 1023. Pressure is 50 to 115kPa correspondingly. //decPcomp = (((unsigned long)siPcomp) * 65000 + 51150000) / 1023; // result in Pa, not kPa decPcomp = (unsigned long)siPcomp; // temporary return decPcomp;} Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
lrf 写道: 手册上说 siPcomp = ((S16)lt3>> 13); 改成这样: siPcomp = ((S16)(lt3>> 13)); 这对我帮助很大。 非常感谢! (加上启动压力/温度转换所需的未记录的 ox01 I2C 写入)。 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我完全同意你的观点,从外部进行校准成本更低,对用户也更开放--只要你了解转换系数值的方法。 好吧,我也看到了你和其他人的程序,不过,并不是每个人都使用 C 语言,当然也不是每个人都使用大内存的 CPU/微处理器,想想看,如果你有 128 字节的内存(RAM),而代码内存(闪存或 ROM)却不足 2K 那么你的设计可能就不一样了。不管怎么说,根据你的经验,每个问题都会在几天后得到解决,而且飞思卡尔的支持人员/工程师都非常乐于助人,这已经是我第三次遇到这样的问题了,但愿今天问题能得到解决,也希望飞思卡尔能给我一些有用的提示。 祝我好运吧 cw. Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
CW、 为什么需要了解数学?如果您想让芯片做一些事情,那么只需使用飞思卡尔在 AN3785 中提供的编程方法,并进行我上面所说的小修改即可。要理解数学原理,只需逆向推导方程式即可。 芯片就是芯片,他们选择的计算方式就是他们选择的方式。在 MC 上进行运算比让芯片进行运算要快得多,也更容易让用户进行调整,而不是让你只能接受运算结果。 要么使用它,要么另寻他处。 我的气象站已经运行了大约一年,没有出现任何问题。它的读数与国家气象局的气压读数完全一致,并根据海拔高度进行了校正(国家气象局的数值是海平面上的)。 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
与在传感器中内置处理器相比,在另一个处理器中进行数学运算要便宜得多,也更容易。我不得不同意,这很难弄懂,但一旦弄懂了就会很好用。 最初的应用说明在系数存储的描述中确实存在一些错误,示例代码取决于处理器的某些字节顺序。 应用程序人员非常乐于助人,在拿到样品部件后的一天左右时间里,我就可以开始使用了。 我在这个论坛上发布了我用来实现这个功能的几乎所有代码,希望其他人能从我的工作中受益。 请回顾本主题中的其他信息,看看这些例子。 如果我有一个改进建议,那就是改善设备上的噪音。读数的跳动确实很大,但拥有内存的高级处理器同样可以轻松实现平滑算法。 祝你好运 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我只是不知道为什么 “飞思卡尔” 把这个设备与所有系数补偿计算混淆而不在内部做!! Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
irf、 “自从我使用这个元器件以来已经有很长时间了,但我可以告诉你,一旦你弄对了数学运算,它就可以正常工作了...” 问题是我无法正确计算数学,我需要你的帮助,你能解释一下如何将 coef' 值转换为纯英语的浮点数,而不是 c 编程表示法。 例如,我从寄存器 $00 - $0f 中读取的数字是 5A C0 75 C0 39 E3 B9 7A CA 7B 32 CC 00 00 00 00 谢谢您的帮助。 cw. Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
自从我使用这个元器件以来已经有很长时间了,但我可以告诉你,一旦你掌握了正确的数学运算,它就可以正常工作了。我发现手册中给出的公式是正确的。不幸的是,我不记得具体是什么问题了,所以我又回头看了一遍我的代码,寻找不同之处。以下是我能找到的唯一区别: 手册上说 siPcomp = ((S16)lt3>> 13); 改成这样: siPcomp = ((S16)(lt3>> 13)); 希望对您有所帮助 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我和其他 MPL115A2 编程用户遇到了同样的问题... 我可以读取寄存器中的数据,但要获得真实的压力和温度,还有很长的路要走、 以下是我从寄存器 $00 至 $0f 中读取的数据 5A C0 75 C0 39 E3 B9 7A CA 7B 32 CC 00 00 00 00 拜托,任何人都可以帮我解开上述数据的奥秘——我知道前四个字节是 Padc 和 Tadc 值,然后是 a0-msb、a0-lsb、b1... c22 等,但是,我不知道如何将这些 No 转换为浮点表示法——实际上我找不到任何提及它的 “飞思卡尔” 文档。 非常感谢你们的帮助。 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
你好 我的 MPL115A2 有问题。 系数数据为 3a 4d ba cc bf a6 31 78 00 00 00 00 Padc = 990 Tadc = 523 我计算着: a0 = 1865.63 b1 = -2.16 b2 = -1.01 c12 = 0.00075 c11 = 0 c22 = 0 Pcomp = -411(负值!!!)。 您有什么想法吗? 非常感谢 ! 尼古拉(意大利) Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
林戈 以下是您两个问题的答案。 1.温度 ADC 无法直接转换为实际温度。您可以尝试改变传感器的环境温度,看看 ADC 值在不同温度下的变化情况。然后你也许就能算出一个换算系数。 2.最终的压力读数是有噪声的,因此将该值转换为海拔高度时也会产生噪声。 通常情况下,压力的变化相当缓慢,因此最好的方法是多次读取数据,并对最后一次测量结果进行平均,以消除噪音。 对于我们的应用,我们每秒进行一次测量,并取过去 100 秒的平均值。 Peter Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
大家的准确性/重复性如何?我的车到处颠簸。 Alt feet:149 Alt feet: 57 Alt feet: 97 Alt feet: 57 Alt feet: 97 Alt feet:109 Alt feet: 57 Alt feet: 45 Alt feet:109 Alt feet: 45 Alt feet:109 Alt feet: 57 Alt feet: 57 Alt feet: 97 Alt feet:109 Alt feet: 97 Alt feet:109 Alt feet: 57 Alt feet:109 Alt feet:109 Alt feet:109 Alt feet: 97 Alt feet:109 Alt feet: 97 Alt feet: 45 Alt feet: 57 Alt feet:109 Alt feet: 97 Alt feet: 57 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
有人能告诉我如何将 uiTADC 数字转换为 c 或 F 吗?我得到的是 523 左右。换算系数是多少? 谢谢 林戈 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
是的,我指的是 C22。我用你的数值计算了压力,结果和你一样。我想我终于意识到自己做错了什么。我看了本主题的第一个帖子,并以此为例转换了系数。所以 C12 是 S0.0000000001110001110000 -> 2^-10 + 2^-11 + 2^-12 + 2^-16 + 2^-17 + 2^-18 = 0.0017281。但符号位为 1(0x38E0)。我是否应该反转 13 个小数位并加 1 以得到真实结果?至于 B2,可能也是同样的错误。感谢您的帮助,PJH! Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我猜你最后一个系数指的是 C22。 在我的一个系统中,我得到了 a0=2156.625000 b1=-2.528809 B2=-1.034241 C12=0.000876 C11=0.000000 C22=0.000000 pressureADC 420 tempADC 419 结果 101.802 kPa。 因此得出的结果是 1018.02 毫巴。 从数值上看,可能出错的是 C12。你的数字比我得到的要小得多。 如果你把我的数字输入你的计算函数,得到的结果和我一样吗? 还请检查 B2 中的小数点位置,您的数字比我的小 10 倍。 不要忘了,您还必须缩放 pComp 值。 输出为 0-1023,刻度为 50kPa 至 115kPa。所以范围是 65 千帕,1023 步。最终压力 = (65/1023*pComp)+50 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
谢谢 PJH,但我相信我的转换是正确的。或者我有吗?目前,Pcomp 的结果是 1067,这不可能是正确的,因为它应该介于 0 和 1023 之间。转换后的系数为 a0 = 2003 b1 = -2.3118 b2 = -0.15836 c12 = 1.456E-10 c11 = 0 c12 = 0 Padc = 370 Tadc = 509 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
系数的大小并不完全相同,但在 x04 到 x0F 的寄存器中打包到 12 字节(96 位)中。系数实际上是浮点数,但是小数点在每个数字中位于不同的位置,有些是负数,等等。因此,由于可能由于数据的字节序性质而无法使示例代码正常工作,因此我编写了一个可以将字节转换为双精度的函数。 首先,这里是下载系数的代码。 显然,I2C 的实现要由读者自己来完成。 void CMPL115A: ownloadCoeffs () { int err=0;int 结果,结果; 字节数据;ia0=0; ib1=0;ib2=0; ic11=0;ic 12=0; ic22=0;//获取 A0 err=m_i 2c.moduleReadByte(晴雨表,0x05,& 数据);if(err=error_Success)//然后我们可能已经连接了一台设备。 因此假定其他呼叫也会成功。 { resultL=INT8(data); m_I2C.ModuleReadByte(BAROMETER,0x04,&data); resultH=INT8(data); iA0=(resultH<< 8)+(resultL&0x00FF); dA0=ConvertCoeffToDouble(iA0,16,12,3,0); // Get B1 m_I2C.ModuleReadByte(BAROMETER,0x07,&data); resultL=INT8(data); m_I2C.ModuleReadByte(BAROMETER,0x06,&data); resultH=INT8(data); iB1=(resultH<< 8)+(resultL&0x00FF); dB1=ConvertCoeffToDouble(iB1,16,2,13,0); // Get B2 m_I2C.ModuleReadByte(BAROMETER,0x09,&data); resultL=INT8(data); m_I2C.ModuleReadByte(BAROMETER,0x08,&data); resultH=INT8(data); iB2=(resultH<< 8)+(resultL&0x00FF); dB2=ConvertCoeffToDouble(iB2,16,1,14,0); // Get C12 m_I2C.ModuleReadByte(BAROMETER,0x0B,&data); resultL=INT8(data); m_I2C.ModuleReadByte(BAROMETER,0x0A,16data); resultH=INT8(data); iC12=(resultH<< 8)+(resultL&0x00FF); dC12=ConvertCoeffToDouble(iC12,14,0,13,9); // Get C11 m_I2C.ModuleReadByte(BAROMETER,0x0D,&data); resultL=INT8(data); m_I2C.ModuleReadByte(BAROMETER,0x0C,&data); resultH=INT8(data); iC11=(resultH<< 8)+(resultL&0x00FF); dC11=ConvertCoeffToDouble(iC11,11,0,10,11); // Get C22 m_I2C.ModuleReadByte(BAROMETER,0x0F,&data); resultL=INT8(data); m_I2C.ModuleReadByte(BAROMETER,0x0E,&data); resultH=INT8(data); iC22=(resultH<< 8)+(resultL&0x00FF); dC22=ConvertCoeffToDouble(iC22,11,0,10,15); m_InitSuccess=true; } else { m_InitSuccess=false; } } 这里是 ConvertCoeffToDouble,它接收 2 字节字,然后是描述位数、整数位、小数位和填充位的参数。可能有更有效的方法可以做到这一点,但是由于在设备初始化时只需要完成一次,因此优化并不重要。 double convertCoeffToDouble(INT16 coeff、短 bitCount、短 IBIT、短 fracBits、短 padBits) { //将系数转换为浮空参数的实用函数。 // 有关如何存储参数的详细信息,请参见飞思卡尔应用说明 AN3785。 double result=0; bool s=false; bool bit; int fb=0; // 我们开始从高位到低位进行处理。 // 传入的数据是一个 16 位整数,我们必须将其缩短,因为如果<16 位,低位 LSB 是空的。(见 AN3785 第 15 页)。 if (bitCount < 16) {//将 coeff 设为适当的大小 coeff =coeff > > (16-bitCount); } //Sanity 检查传递给函数的参数是否有意义。我们的比特数不能多于或少于数据量。 // if((iBits+fracBits+1)!=bitCount) { TRACE(_T("Error in parameters!!\n")); return 0; } //Sanity check that if we are padding of decimal point that we can't also have integer bits. if((padBits>0)&& (iBits>0)) { TRACE(_T("参数错误。iBits 和 padBits 不一致!!\n")); return 0; } for(int b=bitCount;b>0;b--) { bit=bool((int(pow(2.0,b-1)))&coeff)>> (b-1)); // 依次将每个位取为 1 或 0。 if (b==bitCount) // 如果这是第一位(符号位检查是否被设置) { s=bit; if(s) { coeff=~coeff+1; //计算 2 的补码; //(see App note AN3785 middle of Pg15 for explanation)。 } } else // 依次处理比特。 { if(iBits>0) { // 我们有一个整数位; if(bit) { result+=pow(2.0,iBits-1); } iBits--; } else // we have a fractional bit { fb++; if(bit) { result+= (1/pow(2.0,fb+padBits)); } fracBits--; } } } if(s) { result*=-1; } TRACE(_T("Result=%f\n"),result); return result; } 只有在你将所有系数转换为正确的符号、有效数字等之后,事情才会开始变得有意义并能正确读取。 彼得 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
我刚刚从传感器中读取了一些信息。首先,系数 C11 和 C22 均为零。系数是这样的(coeff1 coeff2 ... coeff12): 3E 98 B3 D2 C2 24 38 E0 00 00 00 00 当我计算实际压力(压力 adc = 5C80,温度 adc = 7F40)时,显示为 918 hPa,这不可能是正确的,因为我在海拔 25 米的地方,而海平面的压力应该是 1008 hPa。 非常奇怪的是,C11 和 C22 都为零。有什么想法吗? Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
获得压力是一个多步骤的过程。 首先需要读取压力 ADC 和温度 ADC。 这两个都是 2 字节。 pressureADC= (pressureMSB<< 8+pressureLSB)>> 6; temperatureADC=(tempMSB<< 8+tempLSB)>> 6; 接下来,您需要使用这两个 ADC 值和所有系数来计算压力。 压力= AO+(B1+C11* 压力 ADC+C12* 温度 ADC)* 压力 ADC+(B2+C22* 温度 ADC)* 温度 ADC) 你终于又更正了 pressureC=(65/1023*pressure)+50; 最后得出温度补偿压力(毫巴)。 我发现最难的是正确读取系数。 Peter Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
您好, 我也使用 MPL115A,但使用 SPI,我可以毫无问题地读取温度、压力和系数。 但我不知道如何将 10 位数据转换为以 KPa 或 Celsuis 度接收的数据。 例如: 我得到 MSB 压力 0x5B LSB 压力 0xC0 我是这样做的:0x5BC0>> 6 then Pka = (65/1023)*Padc + 50 但我获得了 73KPa 的气压,而且我并不在 2500 米处 如何获得正确的结果? 谢谢! Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
马克莱曼 这两天我一直在尝试启动新的压力和温度转换,但没有成功。 在 AN3785 中,在 “写入模式” 标题下,它显示了命令并给出了如何编写 “开始两个转换” 字节字符串的示例,该字节字符串显示为: 起始位 从机地址 (0x60) 应答 同时启动两个转换 (0x12) 应答 停止位 但是在 “I2C Simplified” 标题下,它显示在 0x12 字节之后再写一个 0x01 字节,你也可以把它当作自己的代码。你知道 0x01 代表什么吗?除了 "I2C 简化 "页眉外,工作表中其他地方都没有记录,除非我在其他地方没看到。 谢谢您! 罗伯特 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
比尔 你解决过这个问题吗? 马克-莱曼 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
是的,我有 I2C 版本,可以使用 PIC 微型芯片和 NIOS 软 CPU 读取数据,但我做不到的是让系数正常工作。 以下是我使用的代码(您需要自己的 I2C 启动/停止/读取/写入功能) void Measure_ambient_presure(void) { unsigned char x; unsigned char MPL115A2_data[16]; printf(";Read MPL115A2\r"); i2c_start(); // I2C Bus Start condition i2c_write(MPL115A2_I2C_address); // I2C bus Device address i2c_write(MPL115A2_start_both_conversion_command); // Command to Convert both Pressure and Temperature i2c_write(0x01); i2c_stop(); // I2C Bus Stop condition delay_ms(5); // wait for A-D conversion to take place i2c_start(); // I2C Bus Start condition i2c_write(MPL115A2_I2C_address); // I2C bus Device address i2c_write(0x00); // address in MPL115A2 i2c_start(); // I2C Bus Start condition (a restart) i2c_write(MPL115A2_I2C_address|0x01); // address in MPL115A2 + read bit MPL115A2_data[0] = i2c_read(1); // read with ACK MPL115A2_data[1] = i2c_read(1); // read with ACK MPL115A2_data[2] = i2c_read(1); // read with ACK MPL115A2_data[3] = i2c_read(1); // read with ACK MPL115A2_data[4] = i2c_read(1); // read with ACK MPL115A2_data[5] = i2c_read(1); // read with ACK MPL115A2_data[6] = i2c_read(1); // read with ACK MPL115A2_data[7] = i2c_read(1); // read with ACK MPL115A2_data[8] = i2c_read(1); // read with ACK MPL115A2_data[9] = i2c_read(1); // read with ACK MPL115A2_data[10] = i2c_read(1); // read with ACK MPL115A2_data[11] = i2c_read(1); // read with ACK MPL115A2_data[12] = i2c_read(1); // read with ACK MPL115A2_data[13] = i2c_read(1); // read with ACK MPL115A2_data[14] = i2c_read(1); // read with ACK MPL115A2_data[15] = i2c_read(0); // read with noACK i2c_stop(); // I2C Bus Stop condition printf(";MPL115A2 Data= "); for (x=0;x<16;x++) { printf("%02X ",MPL115A2_data[x]); } printf("\r"); } 下面是我从中获得的一些样本数据。 ;MPL115A2 Data= 64 C0 75 80 3D 9B B9 4A C7 46 32 BC 02 20 FD 60 ;MPL115A2 Data= 65 00 76 80 3D 9B B9 4A C7 46 32 BC 02 20 FD 60 ;MPL115A2 Data= 65 40 76 80 3D 9B B9 4A C7 46 32 BC 02 20 FD 60 ;MPL115A2 Data= 65 00 76 C0 3D 9B B9 4A C7 46 32 BC 02 20 FD 60 ;MPL115A2 Data= 65 80 75 C0 3D 9B B9 4A C7 46 32 BC 02 20 FD 60 ;MPL115A2 Data= 65 00 75 40 3D 9B B9 4A C7 46 32 BC 02 20 FD 60 马克-莱曼 Re: MPL115A fixed point question <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
除了 " Billthe Biker " 之外还有其他人尝试过使用 MPL115A 评估板吗。我的板是 i2c 版本,我可以和它通话,但它不想读出任何数据。它只会挂起并锁住电脑。 有人知道吗?我读了比尔关于数学问题的帖子,我担心如果我解决了硬件问题,就会面临数学问题。我在这里买了一头猪吗? 在阅读手册时,我们发现了许多问题,不禁让人怀疑飞思卡尔是否能做到这一点。如蒙回复,不胜感激。(我希望能有比比尔收到的更多的)。
查看全文