簡體   English   中英

C i2c芯片讀取MCP9800突然開始失敗

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM