Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ i2c芯片读取MCP9800突然开始失败_C++_C_Linux_Filter_I2c - Fatal编程技术网

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_读取,而是导致变量损坏的其他错误。我真的不需要处理错误以外的任何事情(又名