TWI zwischen zwei ATMega32

OP #939265
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren