I2C与Atmega168

时间:2017-09-12 02:24:27

标签: embedded i2c atmega servo adafruit

我试图使用adafruit PWM伺服控制器控制多个伺服系统。它使用i2c接口从微控制器进行通信。 https://www.adafruit.com/product/815

我使用Atmega 168尝试使用简单的i2c库将i2c指令发送到微控制器。

*ngFor

我从Arduino驱动程序中找到了伺服控制器的地址,但是我在设置电路板的PWM时遇到了问题。以下是我尝试使用的代码:

#include "i2c.h"

void initI2C(void) {
  TWBR = 32;                               /* set bit rate, see p. 242 */
                                     /* 8MHz / (16+2*TWBR*1) ~= 100kHz */
  TWCR |= (1 << TWEN);                                       /* enable */
}

void i2cWaitForComplete(void) {
  loop_until_bit_is_set(TWCR, TWINT);
}

void i2cStart(void) {
  TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWSTA));
  i2cWaitForComplete();
}

void i2cStop(void) {
  TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWSTO));
}

uint8_t i2cReadAck(void) {
  TWCR = (_BV(TWINT) | _BV(TWEN) | _BV(TWEA));
  i2cWaitForComplete();
  return (TWDR);
}

uint8_t i2cReadNoAck(void) {
  TWCR = (_BV(TWINT) | _BV(TWEN));
  i2cWaitForComplete();
  return (TWDR);
}

void i2cSend(uint16_t data) {
  TWDR = data;
  TWCR = (_BV(TWINT) | _BV(TWEN));                  /* init and enable */
  i2cWaitForComplete();
}

以下是驱动程序:https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library

我很确定我的i2c设置不正确吗?有什么建议吗?

谢谢! :)

1 个答案:

答案 0 :(得分:0)

你的i2c库对于atmega168是错误的。 TWI数据寄存器是一个8位寄存器,您尝试将16位值写入其中。 I2C Not working with PCA9685中的问题使用8位数据TWI(i2c)驱动程序。

i2c已正确初始化,因为它默认为电源供电并且在atmega168复位时计时,您无需关心。但是你应该更好地检查PRR.PRTWI寄存器,如果TWI外围设备是否通电 - 也许你使用一个低功率库来关闭TWI。

此外,您没有明确确保总线上两个字节之间的等待时间,如下所示:Address and 1 Byte Transfer on TWI 在Slave的ACK和写在总线上的下一个数据之后,需要有一个空闲窗口。

所以基本上,你错过了两件大事:

  1. 8Bit数据寄存器需要用1Byte数据写入,而不是用unit16
  2. 由master(you)
  3. 驱动的总线上两个字节之间的显式空闲时间