Сканирование шины I2C с использованием Arduino в качестве ведущего устройства довольно просто, но регистрация трафика без ведущего или ведомого устройства – нет. В интернете вы можете найти несколько проектов снифферов I2C, но далеко не все они функциональны. Поэтому мы разработаем свой собственный.

Чтобы использовать его, вам нужно подключить SDA и SCL к A4 и A5, как если бы это был ведущий или ведомый узел шины I2C.

Проект отлично работает даже с тактовой частотой 400 кГц (как гласит теорема Найквиста-Шеннона, вам всегда нужно делать выборку как минимум с удвоенной частотой сигнала, который вы хотите проанализировать). Двум операторам ассемблера требуется всего 1 + 2 цикла. При F_CPU = 16 МГц он дает частоту выборки 5,33 МГц, что более чем достаточно. Код программы сниффера на основе Arduino следующий:
#define ASM
const byte SDA_mask = 0x10; /* A4 */
const byte SCL_mask = 0x20; /* A5 */
const byte bothHigh = SDA_mask + SCL_mask;
char wr[] = "WR";
void setup() {
Serial.begin(115200);
Serial.println(__FILE__);
Serial.println("SCL SDA");
}
void loop() {
while (PINC == B00110000);
const int N = 500 - 1;
byte b[N];
cli();
#ifdef ASM
asm volatile(
".rept %[count]\n"
"in r0, %[pin]\n"
"st Z+, r0\n"
".endr"
:: "z" (b),
[count] "i" (sizeof b),
[pin] "I" (_SFR_IO_ADDR(PINC))
: "r0"
);
#else
for (int i = 0; i < N; i++) b[i] = PINC;
#endif
sei();
Serial.print("0.1 0.1");
byte sclPrev = 0;
byte sclCnt = 0;
byte adr = 0;
byte data = 0;
for (int i = 0; i < N; i++) {
byte scl = bitRead(b[i], 5);
byte sda = bitRead(b[i], 4);
char out[] = "2 0";
if (scl) out[0]++;
if (sda) out[2]++;
Serial.println(out);
if (scl > sclPrev) {
sclCnt++;
switch (sclCnt) {
case 2 ... 9: adr = adr * 2 + sda; break;
case 11 ... 18: data = data * 2 + sda; break;
}
}
sclPrev = scl;
}
Serial.print("SCL SDA__adr=0x");
if (adr < 32) Serial.print(0);
Serial.print(adr / 2, HEX);
Serial.print("_");
Serial.print(wr[adr & 1]);
Serial.print("_data=");
Serial.println(data);
}
На самом деле, вам придется использовать Serial Plotter "старой" IDE, чтобы увидеть результаты. Декодированные значения будут отображены в заголовке плоттера.

© digitrode.ru