mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frame Error Flag rücksetzen


Autor: Amir B-a (sticky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an alle.
Ich Versuch gerade mit der UART meines ATMega168 eine LIN-Nachricht zu 
empfangen (ATA6662 LIN-Transceiver vorgeshaltet).
Das Erste was ich empfange ist das Sync-Break. Das erkenne ich am 
gesetzten Frame Error Flag im Statusregister. Dieses Frame ist laut 
Datenblatt Read-Only. Ich habe aber das gefühl das ich kein weiteres 
Daten-Byte (Sync-Field entspricht 0x55) erhalten kann, weil das Frame 
Error Flag noch gesetzt ist.

Meine Frage wäre nun, weiß jemand wie man das Frame Error Flag 
rücksetzen kann?

Danke

Gruß Sticky

Autor: Amir B-a (sticky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kennt sich echt keiner damit aus?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Amir B-a schrieb:

> Ich habe aber das gefühl das ich kein weiteres
> Daten-Byte (Sync-Field entspricht 0x55) erhalten kann, weil das Frame
> Error Flag noch gesetzt ist.

Dein Gefühl täuscht dich.

> Meine Frage wäre nun, weiß jemand wie man das Frame Error Flag
> rücksetzen kann?

Gar nicht. Das setzt sich selber zurück, sobald in UDR ein Zeichen 
steht, das korrekt empfangen wurde.

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na ja: Das Datenblatt sagt, daß das Flag gültig ist, bis der 
Receive-Buffer UDRn gelesen wird (es gilt ja auch für ihn speziell). 
Also Buffer auslesen und Inhalt im Zweifelfall verwerfen. Es steht 
übrignes noch viel mehr im Datenblatt zum Thema wann was wie ausgelesen 
und geschrieben werden muß. Ehrlich.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Meine Frage wäre nun, weiß jemand wie man das Frame Error Flag
>rücksetzen kann?

Schon mal Datenblatt gelesen?

S.192 (bei mir):
'Always set this bit to zero when writing to UCSRnA.'

MfG Spess

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
S.192 (bei mir):
'Always set this bit to zero when writing to UCSRnA.'

Schon, aber es ist readonly und soll nur "for compatibility with future 
devices" so geschrieben werden.

Autor: Amir B-a (sticky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Spess
Na klar habe ich das Datenblatt gelesen. Was soll immer diese dumme 
Unterstellung!

Ist es nun wahr, daß das Flag von selbst zurück resetzt wird, wenn im 
Empfangsregister ein gültiges Byte steht?

Wie gesgt ich hatte die Vermutung, daß es nicht zurückgesetzt wird, weil 
ich beim Empfangen des Sync-Felds eine Rote LED einschalte (bei einem 
Frame Error eine grüne) diese rote LED leuchtet nur nie.

Hier der Code
//Funktion Empfangen
uint8_t Receive_Byte(){

uint8_t status;

while (!(UCSR0A & (1<<RXC0)))  // warten bis Zeichen verfuegbar
        ;
status = UCSR0A;
if (status & (1<<FE0)){      //wurde ein Break empfangen?
return 1;
}

else{
return UDR0;          // Zeichen aus UDR an Aufrufer zurueckgeben
}
}
//---------------------
void main(){
//do_Stuff;
}

ISR (USART_RX_vect) {    //Die Interupt Service Routine wird ausgeführt wenn ein zeichen empfangen wird
              
  uint16_t TMPchecksum = 0;
  uint8_t checksum;      //Hier steht die Enhanced Checksumme
  uint8_t ID;          //Hier steht die vom Master versandte ID (ohne Paritätsbits)
  uint8_t PID;        //Hier steht die vom Master versandte ID (mit Paritätsbits)
  uint8_t ID_adr;        //Hier stehen die oberen drei Bits der ID mit der die Baugruppe angesprochen wird
  uint8_t ID_func;      //Hier stehen die unteren drei Bits der ID mit der die Funktionen ausgeführt werden
  uint8_t SyncFeld;
  uint8_t Sync_Break;

  //LIN KOMMUNIKATION STARTET HIER
  Sync_Break=Receive_Byte();
    
  if (Sync_Break){        //Ein Frame Error wird durch ein Sync-Break hervorgerufen
      
    SyncFeld=Receive_Byte();
  

    if (SyncFeld){
      //rote LED an (pseudo)    
        //grüne LED aus

      PID    = Receive_Byte();
      ID    = PID & 0b00111111;               //ID (ohne Paritätsbits)
      ID_adr  = ID >> 3;
      ID_func = PID & 0b00000111; 

      if(Paritaet_Berechnen(PID)) {
      
      DDRC = (0 << DDC4);
      PORTC &= (0<<PC4);//gelbe LED ausschalten

        if ((ID==0) && (Slave_Address==ID_adr)){        
        
          for (uint8_t i=0; i<=6; i++){
            Send_Byte(Daten[i]);              //gesammelte Daten senden
            TMPchecksum= TMPchecksum + Daten[i];  //Checksumme berechnen (CARRY-BIT fehlt noch)!!!!!!!
          }
        
          TMPchecksum = TMPchecksum+PID;        //Enhanced Checksumme!  
          //Low-Byte der checksumme + High-Byte der checksumme
          checksum  = (uint8_t) ((TMPchecksum & 0x00FF) + (TMPchecksum >> 8));        
          checksum= ~checksum;        //Checksumme invertieren
          Send_Byte(checksum);        //anschließend die Checksumme senden
        }

        if ((ID == 1) && (Slave_Address==ID_adr)){    
          Set_RelaisPB1(1);          //Relais1 einschalten
        }

        if ((ID == 2) && (Slave_Address==ID_adr)){    
          Set_RelaisPB1(0);          //Relais1 ausschalten
        }        

        if ((ID == 3) && (Slave_Address==ID_adr)){    
          Set_RelaisPB2(1);          //Relais2 einschalten
        }

        if ((ID == 4) && (Slave_Address==ID_adr)){    
          Set_RelaisPB2(0);          //Relais2 ausschlaten
        }

        if ((ID == 5) && (Slave_Address==ID_adr)){    
          Set_RelaisPB1(1);
          Set_RelaisPB2(1);          //Relais1+2 einschlaten
        }

        if ((ID == 6) && (Slave_Address==ID_adr)){    
          Set_RelaisPB1(0);
          Set_RelaisPB2(0);          //Relais1+2 ausschlaten
        }

        if ((ID == 7) && (Slave_Address==ID_adr)){    
          SW_Reset();              //Reset auslösen
        }
      }//parität
      
      else 
        DDRC = (1 << DDC4);
        PORTC |= (1<<PC4);             //gelbe LED eischalten, somit liegt ein Paritätsfehler vor
    }//syncfeld
  }//FE
}//ISR

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ist es nun wahr, daß das Flag von selbst zurück resetzt wird, wenn im
> Empfangsregister ein gültiges Byte steht?

Ja, ist es.
Aber damit ein gültiges Byte in das Empfangsregister nachrücken kann, 
musst du daraus das fehlerhafte erst mal rausholen. Und genau das tust 
du in deinem Code nicht.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Amir B-a (sticky)

>ich beim Empfangen des Sync-Felds eine Rote LED einschalte (bei einem
>Frame Error eine grüne) diese rote LED leuchtet nur nie.

Besser so.
uint8_t Receive_Byte(){

  uint8_t status, data;

  while (!(UCSR0A & (1<<RXC0)))  // warten bis Zeichen verfuegbar
        ;
  status = UCSR0A;
  data = UDR0;

  if ((status & (1<<FE0)) && data==0){      //wurde ein Break empfangen?
    return 1;
  }
  else{
    return data;          // Zeichen aus UDR an Aufrufer zurueckgeben
  }
}

Wie bereits gesagt, UDR muss man IMMER lesen, sonst gibts Stau, denn 
dann wird RXC0 nicht gelöscht! Siehe Datenblatt. Ausserdem sollte man 
ein Break sicherer detektieren, indem man das empfangene Byte auf Null 
prüft.

MfG
Falk

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was:
Sync_Break=Receive_Byte();
    
  if (Sync_Break){
Wenn Receive_Byte entweder eine 1 oder das Datenbyte liefert, hat dieser 
Code mit dem Erkennen eines Sync-Break nichts zu tun. Auch wenn 
irgendein Datenbyte empfangen wurde ist die Bedingung true.

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.