2017-09-12 60 views
1

我試圖用adafruit PWM伺服控制器來控制幾個伺服器。它使用i2c接口從微控制器進行通信。 https://www.adafruit.com/product/815I2C與Atmega168

我正在使用Atmega 168試圖使用簡單的i2c庫向微控制器發送I2C指令。

#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(); 
} 

,我發現,Arduino的驅動伺服控制器的地址,但我有問題設置主板的PWM。這裏是代碼,我嘗試使用:

#include <avr/io.h> 
#include <util/delay.h> 
#include <avr/interrupt.h> 
#include "i2c.h" 

#define SERVO_MIN 1000 
#define SERVO_MAX 2000 
#define SERVO_MID 1500 

#define PCA9685_ADDR 0x4 

#define PCA9685_MODE1 0x0 

#define LED0_ON_L 0x6 
#define LED0_ON_H 0x7 
#define LED0_OFF_L 0x8 
#define LED0_OFF_H 0x9 

int main(void) 
{ 
    initI2C(); 
    setupController(); 
    for(int i = 1; i < 17; i++) { 
    setServo(i, 0, 4026); 
    } 
    return 0; 
} 

void setupController() { 
    i2cStart(); 
    i2cSend(PCA9685_ADDR); 
    i2cSend(PCA9685_MODE1); 
    i2cSend(0x0); 
    i2cStop(); 
} 

void setServo(uint8_t id, uint16_t start, uint16_t stop) { 
    i2cStart(); 
    i2cSend(PCA9685_ADDR); 
    i2cSend(LED0_ON_L+4*id); 
    i2cSend(start); 
    i2cSend(start>>8); 
    i2cSend(stop); 
    i2cSend(stop>>8); 
    i2cStop(); 
} 

這裏是驅動程序:https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library

我敢肯定我的I2C沒有設置正確?有什麼建議麼?

謝謝! :)

+1

檢查硬件透視圖,SDA和SCL引腳是否被正確拉昇。 –

+0

我做到了,他們是。一切都正確地連接起來。我得出結論,這是我的代碼。我想我可能不會將我的命令發送到正確的寄存器? PWM地址爲0x40 – user2536897

+1

在SDA和SCL引腳上使用DSO和檢查信號,確保它能及時產生信號。首先做基本測試,從主設備發送從設備ID並檢查從設備是否確認。 –

回答

0

您的i2c庫對於atmega168是錯誤的。 TWI數據寄存器是一個8位寄存器,您試圖向其寫入一個16位值。 I2C Not working with PCA9685中的問題使用8位數據TWI(i2c)驅動程序。

i2c已正確初始化,由於默認情況下,它是在默認情況下供電並在atmega168復位時提供的,因此您無需關心。但是,如果TWI外設供電或不供電,您應該更好地檢查PRR.PRTWI寄存器 - 也許您可以使用低功耗的庫來關閉TWI。

此外,您沒有明確保證總線上的兩個字節之間的等待時間,因爲你可以在這裏看到:Address and 1 Byte Transfer on TWI 從屬的ACK和書面總線上的下一個數據後,需要有一個空閒窗口。

因此,基本上,你錯過了兩個主要方面:

  1. 8位數據寄存器需要與數據的1字節不是兩個字節之間由主機驅動總線上的unit16
  2. 明確空閒時間(寫入你)