[英]C i2c chip reading MCP9800 suddenly starts failing
我有一些代码:
#define AMB_LSB 0.0625
void Ambient::read()
{
uint32_t raw;
float filtered;
uint8_t bytes = 2;
uint8_t buf[bytes];
if(i2c_smbus_read_i2c_block_data(i2c_bus_address, A_TEMP_REG, bytes, buf) < 0)
printf("AMB Block Read Failed\n");
uint32_t va = buf[0];
uint32_t vb = buf[1];
uint32_t result = ((va<<8)+vb);
// 12-bit code
raw = result >> 4;
filtered = filter.execfilter( raw );
temperature = filtered * AMB_LSB; << CALCULATION
printf("AMB buffers %d %d -> result %d -> raw %d -> filtered %d -> amb C %f\n",va, vb, result, raw, filtered, temperature);
}
它是通过 i2c 从 MCP9800 读取信息的代码。 很抱歉包含它,但也许它与它有关。
该函数在大约十几个周期内运行良好,直到突然开始出现不正确的值。 但有一些奇怪的差异。
1.如果计算如下
temperature = filtered * AMB_LSB;
我得到这个输出:
temperature = ((float) filtered * (float) AMB_LSB);
在职的
AMB buffers 28 240 -> result 7408 -> raw 463 -> filtered 463 -> amb C 28.937500
AMB buffers 28 240 -> result 7408 -> raw 463 -> filtered 463 -> amb C 28.937500
AMB buffers 28 240 -> result 7408 -> raw 463 -> filtered 1024 -> amb C 64.000000
失败
AMB buffers 29 0 -> result 7424 -> raw 464 -> filtered -**2147483648** -> amb C -134217728.000000
AMB buffers 29 0 -> result 7424 -> raw 464 -> filtered **2147483647** -> amb C 134217728.000000
AMB buffers 29 0 -> result 7424 -> raw 464 -> filtered -**2147483648** -> amb C -134217728.000000
所以一旦它开始失败,我可以看到过滤值的输出不正确。
2.如果计算是:
temperature = raw * AMB_LSB;
所以根本不使用过滤,输出是这样的:
在职的
AMB buffers 29 48 -> result 7472 -> raw 467 -> filtered 0 -> amb C 29.187500
AMB buffers 29 48 -> result 7472 -> raw 467 -> filtered 2147483647 -> amb C 29.187500
AMB buffers 29 64 -> result 7488 -> raw 468 -> filtered 468 -> amb C 29.250000
失败
AMB buffers **255 130** -> result **65410** -> raw **4088** -> filtered 2147483647 -> amb C 255.500000
AMB buffers **255 130** -> result **65410** -> raw **4088** -> filtered -2147483648 -> amb C 255.500000
AMB buffers **255 130** -> result **65410** -> raw **4088** -> filtered 2147483647 -> amb C 255.500000
对于不正确的输出,请参阅星号。 出于某种原因,当您不使用过滤值时,其他数字也开始不正确! 一直回到我从 i2c 芯片上取下的字节。
因此,起初我看到可能已过滤无法正常工作。 但是删除它似乎也会使原始未过滤值也不正确。 所有 execFilter() 所做的都是一些平均以防止大的随机变化。
此外,我还通过使用 i2cget 的 CLI 编写了一个脚本,它的返回值非常一致。 没有崩溃或意外的值。
为什么会发生这种情况?
听起来像是硬件问题。 您的许多值都是 0x7FFFFFFF,例如 SDA 线由上拉电阻控制。 如果 SDA 线上的噪声导致虚假的 I2C 停止条件,就会发生这种情况——设备会立即将其输出设为三态,而在传输的其余部分,您只会得到高位。
建议在 SCL 和 SDA 线上使用 RC 低通滤波器,以减慢边缘并阻止高频噪声,有助于防止此类通信错误。
检查i2c_smbus_read_i2c_block_data()
调用的返回值,而不仅仅是它是否为负。
我敢打赌,当您收到失败的传输时,它会返回 0 或 1。 请记住,实际功能取决于适配器; 如果它不返回错误,我永远不会假设它完全成功,因为它被记录为返回字节数。
它最终导致我的应用程序中另一个类的内存损坏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.