mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik TWI AVR Problem bei Arbitrierung Multimaster Betrieb


Autor: Sebastian S. (bachelor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich habe zwei Atmega32 mit TWI verbunden.

Das senden und empfangen einzeln funktioniert super, habe ganze 
mittlerweile im Mulitmaster Betrieb im Betrieb. Der funktioniert auch 
noch so lange die  Arbitrierung nicht einschreiten muss weil beide 
Controller zu gleichen Zeit anfangen zu senden.
Aus irgendwelchen Gründen kommt die Arbitrierung nicht und der SDA Pin 
bleibt auf Low.

//Senden starten. 

    TWBR = 0b00000001;//Frequenzeinstellung TWI
    TWSR = (1 << TWPS1) | (1 << TWPS0); //Initialisierung TWI
    debug("\r");
      debug("Start senden ");
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE)| (0<<TWEA);
    TWI_zeichen = zeichen;


ISR(TWI_vect)
{
  switch (TWSR & 0xF8) { //TWI Start erfolgreich gesendet
      
    //Empfangs Mode
    
    case 0x60:   // Adresse empfangen und acknowledge gesendet
      debug("");
      debug("SLA+W empfangen");
      TWCR = (1<<TWINT) | (1<<TWEA)| (1<<TWEN)|(1<<TWIE) ;
    break;
    
    case 0x80: // Daten empfangen und acknowledge gesendet
      debug("Daten empfangen");
      //debug(TWDR);
      TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWEA)|(1<<TWIE);
    break;
    
    case 0xA0: // Stop empfangen warte auf neue Adressierung
      debug("Stop empfangen");
      TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(0<<TWSTO)|(0<<TWSTA)|(1<<TWIE);
    break;
    
    //Senden Mode
    
    case 0x08:   
      //debug("TWI Start erfolgreich gesendet Interrupt");
      TWDR = 0x02; //Adresse 1 _ write 0
      TWCR = (1<<TWINT) | (1<<TWEN)| (1<<TWIE);
    
    break;
    
    case 0x38: 
      debug("Aribitration lost");
    break; 
    
    case 0x68: 
      debug("Aribitration lost");
    break; 
    
    case 0x78: 
      debug("Aribitration lost");
    break; 
    
    case 0xB0: 
      debug("Aribitration lost");
    break;
    
    //Slave auf Adresse geantwortet 
    case 0x18:
      //debug("Slave auf Adresse geantwortet");
    
      //debug("Daten an Slave senden");
      TWDR = TWI_zeichen;
      TWCR = (1<<TWINT) | (1<<TWEN)| (1<<TWIE);
    break;
    //Daten von Slave akzeptiert
    case 0x28:
      //debug("Daten von Slave akzeptiert");
      TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)|(0<<TWSTA)|(1<<TWIE);
      debug("Stop gesendet");
      _delay_ms(75); //Abwarten bis Stop gesendet
      TWCR = (1<<TWEA) |(0<<TWSTO);  //Busfreigabe
      TWAR = 0b00000111; //Adresse setzten
      TWSR = (0 << TWPS1) | (0 << TWPS0);
      TWCR = (1<<TWINT)|(1<<TWEA) | (1<<TWEN) | (1<<TWIE);
    break;
    
  }
}//Ende (TWI_vect)


debug wird per RS232 ausgegeben.

Kann mir jemand weiterhelfen?

Gruß Sebastian

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

der eingestellte Code ist schon mal ein Anfang...

aber wenn du aus "case 0x60: usw." so was wie "case TW_REP_START:" 
machen könntest, würde so mancher hier im Forum eher einen Blick darauf 
werfen.
Symbolische Bezeichnungen sind einfacher zu interpretieren wie 
Bitmuster.

Autor: Sebastian S. (bachelor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deine Antwort! Das hilft mir jedoch nicht weiter!

Weiß vielleicht sonst jemand muss ich die Arbitrierung extra 
einschalten, habe ich im Datenblatt etwas überlesen?

Gruß Sebastian

Autor: Sebastian S. (bachelor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe das Problem mittlerweile gelöst.

Man sollte auch die Restlichen Status Codes abfragen! Dann würde 
auffallen das nicht die Arbitrierung sonder etwas anderes einen Fehler 
ausgelöst hat.

Für alle die den Thread zufällig finden, hier die Lösung.
volatile char TWI_zeichen;
volatile char TWI_empfangen = ' ';
volatile char TWI_status = 0;
volatile int TWI_aktiv = 0;

ISR(TWI_vect) /* Interrupt TWI _vect muss immer an den Namen im Datenblatt angehängt werden
          Leerzeichen werden durch _ ersetzt */
{
  TWI_status = (TWSR & 0xF8);
  switch (TWSR & 0xF8) {
      
    //Empfangs Mode
    
    case 0x60:   // Adresse empfangen und acknowledge gesendet
      TWI_aktiv = 1;
      //lcd_gotoxy(0,30);
      //lcd_writestringP(PSTR("SLA+W empfangen"));
      TWCR = (1<<TWINT) | (1<<TWEA)| (1<<TWEN)|(1<<TWIE) ; //Bisher hat TWEN gefehlt!
    break;
    
    
    case 0x70: 
      lcd_gotoxy(0,0);
      lcd_writestringP(PSTR("70"));
    break;
    
    case 0x80: // Daten empfangen und acknowledge gesendet
      //lcd_gotoxy(0,40);
      //lcd_writestringP(PSTR("Daten empfangen"));
      
      TWI_empfangen = TWDR;
      TWCR = (1<<TWEN)|(1<<TWINT)|(1<<TWEA)|(1<<TWIE);
    break;
    
    case 0x88: 
      lcd_gotoxy(0,0);
      lcd_writestringP(PSTR("88"));
    break;    
    
    case 0x90: 
      lcd_gotoxy(0,0);
      lcd_writestringP(PSTR("90"));
    break;
    
    case 0x98: 
      lcd_gotoxy(0,0);
      lcd_writestringP(PSTR("98"));
    break;
    
    case 0xA0: // Stop empfangen warte auf neue Adressierung
      //lcd_gotoxy(0,60);
      //lcd_writestringP(PSTR("Stop empfangen"));
      TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(0<<TWSTO)|(0<<TWSTA)|(1<<TWIE);
      TWI_aktiv = 0;
    break;
    
    //Senden Mode
    
    case 0x08:   
      //TWI_aktiv = 1;
      //lcd_gotoxy(0,40);
      //lcd_writestringP(PSTR("              "));
      TWDR = 0x06; //Adresse 3 _ write 0
      TWCR = (1<<TWINT) | (1<<TWEN)| (1<<TWIE);
      //lcd_gotoxy(0,40);
      //lcd_writestringP(PSTR("Start gesendet"));
      
    break;
    
    case 0x10: 
      lcd_gotoxy(0,0);
      lcd_writestringP(PSTR("10"));
      TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE);
    break;    
    
    case 0x38: 
      lcd_gotoxy(0,20);
      lcd_writestringP(PSTR("Aribitration lost"));
    break;
    
    case 0x68: 
      lcd_gotoxy(0,20);
      lcd_writestringP(PSTR("Aribitration lost"));
    break;    
    
    case 0x78: 
      lcd_gotoxy(0,20);
      lcd_writestringP(PSTR("Aribitration lost"));
    break;      
    
    case 0xB0: 
      lcd_gotoxy(0,20);
      lcd_writestringP(PSTR("Aribitration lost"));
    break;  
    
    
    //Slave auf Adresse geantwortet
 
    case 0x18:
      //debug("Slave auf Adresse geantwortet");
    
      //debug("Daten an Slave senden");
      TWDR = TWI_zeichen;
      TWCR = (1<<TWINT) | (1<<TWEN)| (1<<TWIE);
    break;
    
    case 0x20: 
      lcd_gotoxy(0,0);
      lcd_writestringP(PSTR("20"));
      TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE);
    break;
    
    //Daten von Slave akzeptiert
    case 0x28:
      //debug("Daten von Slave akzeptiert");
      TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)|(0<<TWSTA)|(1<<TWIE);
      //Stop gesendet
      _delay_ms(40);//Abwarten bis Stop gesendet
      TWCR = (1<<TWEA) |(0<<TWSTO);  //Busfreigabe
      TWAR = 0b00000011; //Adresse setzten
      TWSR = (0 << TWPS1) | (0 << TWPS0);
      TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE);
      TWI_aktiv = 0;
    break;
    
    case 0x30:
      lcd_gotoxy(0,0);
      lcd_writestringP(PSTR("30"));
      TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWSTA);
    break;
    
  }
}


Aufruf der Start-Bedingung als Funktion
int f_TWI_send_zeichen(char zeichen) {
    if(TWI_aktiv == 0){
      TWI_aktiv = 1;
      TWBR = 0b00000001;//Frequenzeinstellung TWI
      TWSR = (1 << TWPS1) | (1 << TWPS0); //Initialisierung TWI
      //lcd_gotoxy(0,30);
      //lcd_writestringP(PSTR("Ss"));
      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE);

      TWI_zeichen = zeichen;
    }
  return 1;
}

Gruß Sebastian

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.