TWI zwischen zwei ATMega32

OP #939265
Hallo,

ich habe eine Frage zum TWI Bus zwischen zwei ATMega32 Controllern.
Das schreiben und lesen vom Master auf den Slave funktioniert soweit 
schon ganz gut. Jetzt habe ich aber das Problem, dass ich in der TWI 
Botschaft Befehle verschicken möchte, die den Slave veranlassen, 
bestimmte Aktionen auszuführen.

Auf dem Slave läuft folgende ISR:

ISR (TWI_vect)
{
  uint8_t data=0;
  switch (TW_STATUS)
  {
    case TW_SR_SLA_ACK:
       TWCR_ACK;
       buffer_adr=0xFF;
    break;

    case TW_SR_DATA_ACK:
       data=TWDR;
    if (buffer_adr == 0xFF)
    {
      if(data<=buffer_size)
      {
        buffer_adr= data;
      }
      else
      {
        buffer_adr=0;
      }
      TWCR_ACK;
    }
    else
    {
      rxbuffer[buffer_adr]=data;
      buffer_adr++;
      if(buffer_adr<(buffer_size-1))
      {
        TWCR_ACK;
      }
      else
      {
        TWCR_NACK;
      }
    }
    break;

    case TW_ST_SLA_ACK:
    case TW_ST_DATA_ACK:

    if (buffer_adr == 0xFF)
    {
      buffer_adr=0;
    }
    TWDR = txbuffer[buffer_adr];
    buffer_adr++;
    if(buffer_adr<(buffer_size-1))
    {
      TWCR_ACK;
    }
    else
    {
      TWCR_NACK;
    }
    break;

    case TW_ST_DATA_NACK:
    case TW_SR_DATA_NACK:
    case TW_ST_LAST_DATA:
    case TW_SR_STOP:
    default:
              TWCR_RESET;
    break;
  }
}

Der Befehl der vom Master kommt ist folgendermassen aufgebaut:

i2c_start_wait(adresse_slave+I2C_WRITE);
i2c_write(0x00);
i2c_start_wait(adresse_slave+I2C_WRITE);
i2c_write(i2c_param1);
i2c_write(i2c_param2);
i2c_write(i2c_param3);
i2c_write(i2c_param4);
i2c_write(i2c_param5);
i2c_write(i2c_param6);
i2c_write(i2c_param7);
i2c_write(i2c_param8);
i2c_stop();

der Paramwert1 soll den eigentlichen Befehl enthalten.

Wie müsste ich meine ISR umbauen, damit das ganze so funktionieren kann?

danke und Gruß
Gast #940365
Moin Moin !
Der Programmcode kommt mir sehr bekannt vor ... von Roboternetz gelle ;)
Im Prinzip hast du ja schon alles was du brauchst und das wäre dein 
Empfangsbuffer unter dem Punkt TW_SR_DATA_ACK:. Hier wird der 
Payloadkram ja in einem Buffer untergebracht.

- anlegen einer bool Variablen, welche auf TRU gesetzt wird wenn unter 
TW_SR_DATA_ACK: neue Daten empfangen wurden.

- Abfragen der Variablen in der main loop.

- Falls TRU, Funktion aufrufen, in der du den Buffer auf valide 
Befehlsdaten hin überprüft. buffer[0] == Befehl ?

- definieren einer State Variablen.

- Jeder Befehl bekommt eigenen State zugeordnet welcher in der State 
Variabln gesetzt wird.

- Wenn valider Befehl erkannt wurde, Aufruf einer 2en Funktion, welcher 
du den aktuellen State übergibst. Je nach gesetztem State wird der 
Befehl abgearbeitet.

- State zurücksetzen (default).

- das ganze Spiel von vorne

mfG

der Verwickler
OP #941358
Hallo,

stimmt genau. Der Code für den Slave ist von Roboternetz. Den Teil vom 
Master habe ich so von meiner RTC Ansteuerung für die DS1337C 
übernommen. Das Funktioniert wunderbar.
Ich kann wie gesagt Werte in den rxbuffer schreiben und die Werte aus 
dem txbuffer auslesen.
Das Problem mit der Befehlsausführung habe ich inzwischen so gelöst, 
dass ich als letzten Parameterwert einen eindeutigen Befehl schicke und 
dann die empfangenen Daten in der ISR daraufhin überprüfe.
Wenn der Befehl empfangen wurde, springt das Programm in die 
Befehlsauswahl wenn nicht, wird "einfach weiterempfangen".
Hier mal der Code dazu.

if (data == 0x7E)
{
    auswahl();
}
else
{
    ;
}

ist vielleicht nicht die beste Lösung aber funktioniert bis jetzt ganz 
gut.

mfg

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.