错误地发送了有关I2C Arudino UNO的数据

时间:2017-03-30 11:48:24

标签: c++ arduino i2c

我正在运行下面的代码,在Arduino UNO rev3上执行I2C环回接口。 Arduino板充当I2C总线中的从器件,在接收到数据包后,它会引发一条线,触发主器件的读操作。 Arduino只是回答了它首先收到的相同数据。以下代码似乎运作良好:

#include <stdint.h>
#include <Wire.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif

#define I2C_DATA_SIZE 350
#define I2C_IRQ_PIN   13
typedef struct {
  uint8_t   data[I2C_DATA_SIZE];
  uint16_t  count;
  uint16_t  size;
  bool      ready;
} i2c_packet_t;

static i2c_packet_t i2c_pkt;

void setup() {
  Serial.begin(115200);           // start serial for output

  Wire.begin(0x29);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent);
  memset(&i2c_pkt, 0, sizeof(i2c_packet_t));
  pinMode(I2C_IRQ_PIN, OUTPUT);
  digitalWrite(I2C_IRQ_PIN, false);

  /* Disable internall pullups */
  #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
    // deactivate internal pull-ups for twi
    // as per note from atmega8 manual pg167
    cbi(PORTC, 4);
    cbi(PORTC, 5);
  #else
    // deactivate internal pull-ups for twi
    // as per note from atmega128 manual pg204
    cbi(PORTD, 0);
    cbi(PORTD, 1);
  #endif


}

void loop() {
  digitalWrite(I2C_IRQ_PIN, i2c_pkt.ready);
  delay(100);
}

void requestEvent(void) {
  digitalWrite(I2C_IRQ_PIN, false);
  Wire.write(i2c_pkt.data, i2c_pkt.size);
  memset(&i2c_pkt, 0, sizeof(i2c_packet_t));
}

void receiveEvent(int howMany) {
  if (i2c_pkt.count == I2C_DATA_SIZE) {
    Serial.println("I2C packet too large");
  }
  for (int i = 0; i < howMany; i++) {
    i2c_pkt.data[i2c_pkt.count++] = Wire.read();
    if (i2c_pkt.count == 2) {
      i2c_pkt.size = (i2c_pkt.data[0] << 8) | i2c_pkt.data[1];
      i2c_pkt.ready = true;
    }
  }
}

我知道Wire回调在I2C中断上运行,所以我试图将Wire.write()位移到loop()。我只是在i2c_packet_t中添加了请求,现在loop()requestEvent()看起来像这样:

void loop() {
  digitalWrite(I2C_IRQ_PIN, !i2c_pkt.request && i2c_pkt.ready);
  if (i2c_pkt.request) {
      if (i2c_pkt.ready) {
      digitalWrite(I2C_IRQ_PIN, false);
      Wire.write(i2c_pkt.data, i2c_pkt.size);
      memset(&i2c_pkt, 0, sizeof(i2c_packet_t));
    } else {
      Serial.println("ERROR: I2C request but no data available");
    }
  }
}

void requestEvent(void) {
    i2c_pkt.request = true;
}

出于某种原因,该解决方案不起作用:主设备始终接收&#34; 0xFF&#34;。我使用Nordic开发板作为主机,它作为SDA和SCL线路上的内部上拉电阻。

这让我很困惑,所以欢迎任何想法。

0 个答案:

没有答案