Linkit 7697 + IMU 10DOF v2.0 研讀紀錄(一)
Linkit 7697 + IMU 10DOF v2.0 研讀紀錄(二):I2Cdev::readBites()
Linkit 7697 + IMU 10DOF v2.0 研讀紀錄(三):三軸感應器

改用Arduino UNO WiFi來測試I2Cdev::readBits()這隻程式,另外又增加了一點偵錯碼,使得內容可以更精確地呈現

int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout) {
    // 01101001 read byte
    // 76543210 bit numbers
    //    xxx   args: bitStart=4, length=3
    //    010   masked
    //   -> 010 shifted
    uint8_t count, b;
    if ((count = readByte(devAddr, regAddr, &b, timeout)) != 0) {
        #ifdef I2CDEV_SERIAL_DEBUG
            Serial.println("\nI2Cdev::readBits()");
            Serial.print("bitStart = ");
            Serial.print(bitStart, DEC); 
            Serial.print("; length = ");
            Serial.print(length, DEC); 
            Serial.print("; b (before) = 0x");
            Serial.print(b, HEX);            
        #endif
        uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
        uint8_t i = -1;
        uint8_t mask2 = ((1 << length) - 1) << i;

        b &= mask;
        #ifdef I2CDEV_SERIAL_DEBUG
            Serial.print("; b (after mask) = 0x");
            Serial.print(b, HEX);            
        #endif
        b >>= (bitStart - length + 1);
        *data = b;
        #ifdef I2CDEV_SERIAL_DEBUG
            Serial.print("; mask = 0x");
            Serial.print(mask, HEX);
            Serial.print("; b (after) = 0x");
            Serial.println(b, HEX); 
            Serial.println("testing for data format:");
            Serial.print("mask2 = 0x");
            Serial.println(mask2, HEX);

            b = 0x71;
            Serial.print("\n直接運算:b  = 0x71");
            Serial.print("; b << 1 = 0x");
            Serial.print(b << 1, HEX);
            Serial.print("; b << -1 = 0x");
            Serial.print(b << -1, HEX);
            Serial.print("; b >> -1 = 0x");
            Serial.println(b >> -1, HEX);

            Serial.print("使用代數運算:mask = 0x");
            Serial.print(mask, HEX);
            Serial.print("; mask2 = 0x");
            Serial.println(mask2, HEX);
            
            Serial.println("變數型別與使用空間判斷:");
            Serial.print("(bitStart - length + 1) = 0x");
            Serial.print((bitStart - length + 1), HEX);
            Serial.print(" = ");
            Serial.print((bitStart - length + 1), DEC);
            Serial.print("; sizeof (bitStart - length + 1) = ");
            Serial.print(sizeof (bitStart - length + 1));
            Serial.println("bytes");
            Serial.print("(6 - 8 + 1) = 0x");
            Serial.print(6 - 8 + 1, HEX);
            Serial.print(" = ");
            Serial.print(6 - 8 + 1, DEC); 
            Serial.print(";  sizeof (6 - 8 + 1) = ");
            Serial.print(sizeof (6 - 8 + 1));
            Serial.println("bytes");
            Serial.print("i = 0x");
            Serial.print(i, HEX);
            Serial.print(" = ");
            Serial.print(i, DEC); 
            Serial.print(";  sizeof (i) = ");
            Serial.print(sizeof i);
            Serial.println("bytes");
        #endif
    }
    return count;
}

輸出結果

bitStart = 6; length = 8; b (before) = 0x71; b (after mask) = 0x71; mask = 0x7F; b (after) = 0x71
testing for data format:
mask2 = 0x0

直接運算:b  = 0x71; b << 1 = 0xE2; b << -1 = 0x71; b >> -1 = 0x71
使用代數運算:mask = 0x7F; mask2 = 0x0
變數型別與使用空間判斷:
(bitStart - length + 1) = 0xFFFFFFFF = -1; sizeof (bitStart - length + 1) = 2bytes
(6 - 8 + 1) = 0xFFFFFFFF = -1;  sizeof (6 - 8 + 1) = 2bytes
i = 0xFF = 255;  sizeof (i) = 1bytes

觀察一下程式碼22行、26行,以及在38~45做的測試,發現在Arduino UNO WiFi上面「>> -1 」,和「 << +1」是不會被執行的,但如果先將「-1」型別轉換成unit8_t,會形成「>> 255」的結果。

最後,Arduino UNO WiFi所使用的晶片是8bits的ATmega328,而Linkit 7697所使用的晶片是32位元的ARM Cortex-M4。

發佈留言