Beim Initialisieren gibst Du dem AVR die gleiche Adresse, die auch dein Sensor hat. Ich bin nicht sicher, ob dies Deinen Fehler auslöst. In meinem Source lasse ich dieses Register im Default Zustand.
Ich sehe in Deinem Source sonst keinen Fehler. Ich habe meinen Sensor inzwischen ans Laufen bekommen, mein Fehler war, dass ich als Befehl 0x81 anstatt 81 gesendet hatte.
Versuch mal meinen Source:
Code:
void i2c_init() {
// I2C Bus ca. 100khz Taktfrequenz
TWBR=75;
}
uint8_t i2c_write(uint8_t slave_id, uint8_t address, uint8_t data) {
// Sende START
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
while (!(TWCR & (1<<TWINT))) yield();
uint8_t status=TWSR & 0xf8;
if (status != 0x08 && status != 0x10) goto error;
// Sende Adresse des Sensors
TWDR=slave_id;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x18) goto error;
// Sende Register Nummer
TWDR=address;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x28) goto error;
// Sende Befehl (Messen in Zentimeter)
TWDR=data;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x28) goto error;
// Sende STOP
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
return 0;
error:
// Sende STOP
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
return 255;
}
uint8_t i2c_read(uint8_t slave_id, uint8_t address) {
uint8_t result=0;
// Sende START
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
while (!(TWCR & (1<<TWINT))) yield();
uint8_t status=TWSR & 0xf8;
if (status != 0x08 && status != 0x10) goto error;
// Sende Adresse des Sensors
TWDR=slave_id;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x18) goto error;
// Sende Register Nummer
TWDR=address;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x28) goto error;
// Sende wiederholt START
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
while (!(TWCR & (1<<TWINT))) yield();
status=TWSR & 0xf8;
if (status != 0x08 && status != 0x10) goto error;
// Sende Adresse des Sensors (read mode)
TWDR=slave_id+1;
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x40) goto error;
// lese ein Byte ohne ACK
TWCR=(1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))) yield();
if ((TWSR & 0xf8) != 0x58) goto error;
result=TWDR;
// Sende STOP
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
return result;
error:
// Sende STOP
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
return 255;
}
uint16_t distance() {
// Sende Ping Befehl
i2c_write(0xE0,0,81);
// Warte, bis Ergebnis verfügbar ist
while (i2c_read(0xE0,0)==255);
// Lese das Ergebnis aus
return (uint16_t) i2c_read(0xE0,2)*255 +i2c_read(0xE0,3);
}
Ich habe einen ATmega16 mit 15Mhz verwendet.
Lesezeichen