Forum: Compiler & IDEs TWI zwischen zwei ATMega32


von Florian M. (skywalker79)


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ß

von Verwickler (Gast)


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

von Manni (Gast)


Lesenswert?

Ich habe so was mal in die Codesammlung gestellt....

[[Beitrag "AVR TWI Master und Slave Funtionen in C"]]

Manni

von Florian M. (skywalker79)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.