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。