为什么 I2C 通信在第二次通过相同代码时失败?
Why is the I2C communication failing on a second pass through the same code?
概况 - 我有一个执行很多任务的 MCU。它将 I2C 从通信公开给 Raspberry Pi。我在 MCU 上的代码中创建了许多 'registers'。所有这些都工作正常。我之前连接了一个 nano 并测试了 MCU 上的所有内容,因此我相当确定 MCU 运行正常。我的大部分 I2C 通信也在 Pi 上工作。除了一个。有点不同的是,它写了三个字节。
这是我的 RPi 代码:
std::string i2cServo(uint8_t reg, uint8_t angle){
std::string error;
uint8_t TxBuf[3];
TxBuf[0] = 11; // The register.
TxBuf[1] = reg; // The first parameter.
TxBuf[2] = angle; // The second parameter.
close_fd();
if (!fd) {
if (open_fd_wronly() == -1) {
error = "Failed to open I2C bus.";
} else {
if (write(fd, &TxBuf, 3) != 3) {
std::cerr << errno << std::endl;
error = "Could not set servo.";
}
}
}
return error;
}
这段代码被执行了两次。第一次一切正常,第二次我得到 errno 5。这是 EIO。
这是逻辑分析仪的输出:
可以看到第一关没问题。第二遍也很好,直到结束时预计会停止。
如果不是因为 nano 行为正确并且代码的第一遍工作正常,我会怀疑 MCU。
有什么想法吗?
这是fd开头:
int open_fd_wronly(){
error_flag = false;
if (fd) {
close_fd();
fd = 0;
}
if ((fd = open(devicefile.c_str(), O_WRONLY)) < 0)
return errorMsg("ERROR opening: " + devicefile + "\n");
if (ioctl(fd, I2C_SLAVE, slave_address) < 0)
return errorMsg("ERROR address: " + std::to_string(slave_address) + "\n");
return 0;
}
抱歉,刚发布问题。我突然明白了答案。分享问题真的很有帮助。第一个寄存器调用提示写入 EEPROM,第二个调用到达得太快触发了对 EEPROM 的另一次写入并导致崩溃。两次通话之间的一点延迟解决了这个问题。
非常感谢。
概况 - 我有一个执行很多任务的 MCU。它将 I2C 从通信公开给 Raspberry Pi。我在 MCU 上的代码中创建了许多 'registers'。所有这些都工作正常。我之前连接了一个 nano 并测试了 MCU 上的所有内容,因此我相当确定 MCU 运行正常。我的大部分 I2C 通信也在 Pi 上工作。除了一个。有点不同的是,它写了三个字节。
这是我的 RPi 代码:
std::string i2cServo(uint8_t reg, uint8_t angle){
std::string error;
uint8_t TxBuf[3];
TxBuf[0] = 11; // The register.
TxBuf[1] = reg; // The first parameter.
TxBuf[2] = angle; // The second parameter.
close_fd();
if (!fd) {
if (open_fd_wronly() == -1) {
error = "Failed to open I2C bus.";
} else {
if (write(fd, &TxBuf, 3) != 3) {
std::cerr << errno << std::endl;
error = "Could not set servo.";
}
}
}
return error;
}
这段代码被执行了两次。第一次一切正常,第二次我得到 errno 5。这是 EIO。
这是逻辑分析仪的输出:
可以看到第一关没问题。第二遍也很好,直到结束时预计会停止。
如果不是因为 nano 行为正确并且代码的第一遍工作正常,我会怀疑 MCU。
有什么想法吗?
这是fd开头:
int open_fd_wronly(){
error_flag = false;
if (fd) {
close_fd();
fd = 0;
}
if ((fd = open(devicefile.c_str(), O_WRONLY)) < 0)
return errorMsg("ERROR opening: " + devicefile + "\n");
if (ioctl(fd, I2C_SLAVE, slave_address) < 0)
return errorMsg("ERROR address: " + std::to_string(slave_address) + "\n");
return 0;
}
抱歉,刚发布问题。我突然明白了答案。分享问题真的很有帮助。第一个寄存器调用提示写入 EEPROM,第二个调用到达得太快触发了对 EEPROM 的另一次写入并导致崩溃。两次通话之间的一点延迟解决了这个问题。 非常感谢。