C++ i2c芯片读取MCP9800突然开始失败
我有一些代码:C++ i2c芯片读取MCP9800突然开始失败,c++,c,linux,filter,i2c,C++,C,Linux,Filter,I2c,我有一些代码: #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 B
#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);
}
我得到这个输出:
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 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 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
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
因此,一旦它开始失败,我可以看到过滤值的输出是不正确的
2.如果计算为:
temperature = raw * 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 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 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
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()所做的只是进行一些平均,以防止出现较大的随机更改
此外,我还通过CLI编写了一个使用i2cget的脚本,它的返回值非常一致。没有崩溃或意外值
为什么会发生这种情况?听起来像是硬件问题。您的许多值为0x7FFFFFFF,例如,SDA线路由上拉电阻器控制。如果SDA线路上的噪声导致虚假的I2C停止条件,则会发生这种情况——设备将立即将其输出三态化,并且在剩余的传输过程中,除了高位之外,您将一无所获
建议在SCL和SDA线路上使用RC低通滤波器,以降低边缘速度并阻断高频噪声,有助于防止此类通信错误。检查来自
i2c\u smbus\u read\u i2c\u block\u data()
调用的返回值,而不仅仅是它是否为负值
我打赌当你得到失败的传输时,它会返回0或1。记住,实际的功能取决于适配器;如果它不返回错误,我决不会认为它完全成功,因为它被记录为返回字节数。它最终导致应用程序中另一个类的内存损坏
注意,而不是
((vaWe也在我的工作环境中观察到i2c通信会因为这些原因而受损,特别是对于在同一块板上有HF处理的硬件。如果发生了这样的硬件问题,您可以从错误代码中知道。i2c从从机有每个字节的ACK。因此,如果从机停止响应,主机将检测到NACK c条件和驱动程序将返回错误。@g-makulik:对。如果产生噪声的其他电路未激活,独立测试可能看不到相同的错误。@TJD:否。I2C具有来自接收方(在读取传输期间为主设备)的每字节确认。从设备仅确认初始设备地址,这对检测错误没有帮助纯粹的停止条件。@BenVoigt是的,它很害怕出现错误并且很难调试!特别是如果i2c com是在软件中实现的(只是切换gpios)。你是对的。我检查了一下,它始终返回“2”即使值失败。这只是证实了我的怀疑,即它根本不是i2c_读取,而是导致变量损坏的其他错误。我真的不需要处理错误以外的任何事情(又名