www.mikrocontroller.net

Forum: Compiler & IDEs TWI zwischen zwei ATMega32


Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Verwickler (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Manni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe so was mal in die Codesammlung gestellt....

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

Manni

Autor: Florian M. (skywalker79)
Datum:

Bewertung
0 lesenswert
nicht 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

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.