Hi PicNick,
ich hab' mal die Endlosschleife beim Slave ergänzt (das fehlende TWDR war zu Testzwecken, er sollte mir den Statuscode zurückgeben); so schauts momentan aus:
Slave:Master:Code:#include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include <util/twi.h> uint8_t i2c_getbyte(void); void i2c_init(uint8_t Adress); uint8_t i2c_status(void); int main (void) { DDRD = 0xFF; uint8_t buffer = 0; i2c_init(26); while(1) { buffer = i2c_getbyte(); //Empfangen des Bytes PORTD = buffer; //Ausgabe zur Kontrolle } return(0); void i2c_init(uint8_t Adress) { TWSR = 0; TWAR = (Adress << 1); TWCR = (1 << TWEA) | (1 << TWEN) | (0 << TWSTA) | (0 << TWSTO); } uint8_t i2c_getbyte(void) { uint8_t Status = 0; uint8_t Byte = 0; //Warten, bis der Slave angesprochen wurde Status = i2c_status(); Byte = TWDR; TWCR = (1 << TWINT) | (1 << TWEA) | (1 << TWEN) | (0 << TWSTA) | (0 << TWSTO); //TWINT-Bit zurücksetzen, um nächste Aktion auszulösen return(Byte); } uint8_t i2c_status() { //Warten, bis das Interrupt-Bit gesetzt und so das erfolgreiche Ende einer Busaktion angekündigt wurde while(!(TWCR & (1 << TWINT))); //Ausmaskieren der Prescaler-Bits und Rückgabe des Statuswertes return(TWSR & 0xF8); }Ich habe mir die Statuscodes beim Master mal angesehen, da schauts so aus, als ob er kein ACK vom Slave bekommt, obwohl bei diesem das TWEA-Bit gesetzt ist.Code:#include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include <util/twi.h> void i2c_init (void); uint8_t i2c_sendbyte (uint8_t Adress, uint8_t Data); uint8_t i2c_status (void); volatile uint8_t TWIStatus = 0; int main (void) { DDRD = 0xFF; uint8_t Status = 0; i2c_init(); Status = i2c_sendbyte (26,15); PORTD = Status; //Ausgabe des Status zu Debugzwecken while(1); return(0); } void i2c_init (void) { //Einstellen des Bustaktes auf 400kHz: TWSR = 0; TWBR = 12; } uint8_t i2c_sendbyte (uint8_t Adress, uint8_t Data) { uint8_t TWIStatus = 0; //Variable für Fehlercode //Senden der Startbedingung und zurücksetzen des Flags: TWCR = (1 << TWSTA) | (1 << TWEN); //Warten auf Abschluss der Aktion: TWIStatus = i2c_status(); /* -------------------------------------------------------------------------- */ /* Falls der Bus nicht gerade als "busy" gesetzt ist, wurde das TWI-Interrupt */ /* Bit gesetzt, der Statuswert kann nun ausgelesen werden. */ /* Ist kein Fehler aufgetreten, kann die Adresse mit gesetztem Write-Bit */ /* ausgegeben werden. */ /* -------------------------------------------------------------------------- */ PORTD = TWIStatus; if ((TWIStatus == 0x08) || (TWIStatus == 0x10)) { //Zugriff auf Bus erlaubt, nun wird die Slaveadresse mit gesetztem Write-Bit ausgegeben: TWDR = (Adress << 1) & 0xFE; TWCR = (1 << TWINT) | (1 << TWEN) | (0 << TWSTA); //TWINT-Bit zurücksetzen, um nächste Aktion auszulösen //Warten auf Abschluss der Aktion: TWIStatus = i2c_status(); PORTD = TWIStatus; if (TWIStatus == 0x18) { //Slaveadresse wurde erfolgreich gesendet, nun können Daten verschickt werden: TWDR = Data; TWCR = (1 << TWINT) | (1 << TWEN); //TWINT-Bit zurücksetzen, um nächste Aktion auszulösen //Warten auf Abschluss der Aktion: TWIStatus = i2c_status(); PORTD = TWIStatus; if ((TWIStatus == 0x28) || (TWIStatus == 0x30)) { TWIStatus = 255; //kein Fehler } } } //Senden der Stoppbedingung: TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); return(TWIStatus); } uint8_t i2c_status() { //Warten, bis das Interrupt-Bit gesetzt und so das erfolgreiche Ende einer Busaktion angekündigt wurde while(!(TWCR & (1 << TWINT))); //Ausmaskieren der Prescaler-Bits und Rückgabe des Statuswertes return(TWSR & 0xF8); }
Viele Grüße







Zitieren

Lesezeichen