www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART1 problem beim ATMEGA128


Autor: Henrik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
nach Stunden der Fehlersuche mit meinem ATMEGA128 weiß ich nicht mehr 
weiter.
Folgende Situation:
Ich betreibe mit einem ATMEGA128 beide UARTS. UART0 läuft einwandfrei. 
UART1 sendet Daten, ist aber nicht in der Lage Daten zu empfangen.
Beide Schnittstellen laufen auf 9600B 8N1, beide Schnittstellen werden 
gepollt betrieben.
Für UART1 habe ich auch eine Interrupt- Variante ausprobiert. Auch hier 
keine Regung.
Die Gegenstelle ist geprüft und sendet die Antworten korrekt zurück an 
UART1( per Oszi direkt am RxD1 Pin des ATMega128 gemessen).
M103C Fuse ist nicht gesetzt.

Hier der Code zum versenden und empfangen eines Befehls.
int Modul_on (void){

com2_puts_P(OM_Modul_ON);
  
  //Antwort des Moduls
  if (getModulAnswer()==FALSE)
    {com1_puts_P(ERR_Modul_ON);
    return FALSE;
    }
  }
return TRUE;
}




hier die getModulAnswer() zum Empfang der Antwort.

uint8_t getModulAnswer(){
  ModulPortValue=0;
  i_lsr=0;
  LSRTimeOut = TIMEOUTLSR;
  
  
    
  while (ModulPortValue != 0x0d)  //auf Carriage return warten
    {
    //auf zeichen warten
    while( (!(UCSR1A & (1<<RXC1))) || (LSRTimeOut!=0) ) 
      {//Timeout
      _delay_ms(10);
      LSRTimeOut--;
      }
    

    //war es ein Timeout?
    if (LSRTimeOut==0)
      {
      return FALSE;
      }
    else {LSRTimeOut = TIMEOUTLSR;}
  
    //Empfangenes Zeichen speichern
    ModulPortValue = UDR1;
    
          
    if (ModulPortValue == 0x0d) com2Buffer[i_lsr]=0;
    else com2Buffer[i_lsr]=ModulPortValue;
    i_lsr++;
    }
  return TRUE;
}


Schon mal vor ab Danke für jeden Tip!

Gruß,
Henrik

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir persönlich bereitet die Rückkehr mit Return aus einer while-Schleife 
heraus Bauchschmerzen, aber naja.

Dein Code ist nicht nützlich. Zwar könnte da theoretisch auch ein Fehler 
liegen, aber wesentlich ist erstmal der eigentliche Datenempfang, die 
Initialisierung der UARTs die Du hier nicht zeigst und die Hardware.
Das aber prüfst Du am besten mit einem Minimslprogramm, das die 
empfangenen Zeichen zurücksendet.

Autor: Andreas Vogt (tico)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du die Versorgungsspannung an allen entsprechenden Pins korrekt 
angeschlossen? Insbesondere auch an AVCC (Pin 64) ?

Gruss
Andreas

Autor: Henrik (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Das geht ja schnell... Danke.
zur Vervollständigung der Infos:
Init der Schnittstelle
void com2_Init(uint32_t baudRate, uint32_t quarzClock) {

  // Baud Rate setzen
  UBRR1H = (uint8_t)(((quarzClock)/((baudRate)*16l)-1)>>8);
  UBRR1L = (uint8_t)((quarzClock)/((baudRate)*16l)-1);
  
         UCSR1B = 0x18;

  //asynchronous 8N1
  UCSR1C = 0x06;  

  UCSR1A = 0x00;
}


Der  eigentliche Datenempfang befindet sich in der Funktion
getModulAnswer(); siehe oben :

//auf zeichen warten
    while( (!(UCSR1A & (1<<RXC1))) || (LSRTimeOut!=0) ) 
      {//Timeout
      _delay_ms(10);
      LSRTimeOut--;
      }
LSRTimeOut ist ein Timeout- Counter der hier die Endlosschleife 
verhindern soll. Ansonsten wird auf Receive completed des UCSR1A 
Registers gepollt.
Das Verhalten ist also stand jetzt immer ein Timeout.
Der Timeout wird pro Zeichen rückgesetzt und liegt bei 250ms. Per Oszi 
habe ich ermittelt, dass die Antwort des Zielsystems innerhalb von 
10-20ms erfolgt (timeout sollte somit ausreichen).

@Huch: Mit dem Return in der Schleife geb ich dir recht, is unsauber. 
Werde den Timeout ebenfalls in die äußere Schleife setzen und den 
Rücksprung bedingt außerhalb der Schleifen durchführen. Als 
Fehlerursache kann ich es mir jedoch nicht vorstellen, habe zuvor auch 
ohne Timeout gearbeitet, was einen Dead Lock zur folge hatte.

Nochmal zur erläuterung des Fehlerverhaltens:
UART1 sendet --> OK
Zielsystem reagiert --> OK
Zielsystem antwortet --> Ich sehen die zeichen auf dem Scope 
ankommen,wenn ich an PIN27 (PD2/RxD1) von meinem ATMEGA128 messe!
-->RXC1 wird trotzdem nie gesetzt.

In sachen Hardware:
an UART0 --> PC, Hyperterinal
an UART1 --> weitere MC basierte Elektronik. Dieses System ist ein 
Kaufteil und bereits öfters im Einsatz. Kann ich leider nicht als 
mögliche Fehlerursache anführen.
Beide Rx und Tx leitungen sind vom ATMEGA128 auf ein MAX232ACSE geführt. 
Betriebsspannung des MAX und Kondensatorwerte des Prototypboards sind 
überprüft.
Schalplanauszug ist beigefügt.

@Andreas: Im Schaltplan ist er Angeschlossen. Messung am Pin64,52,21 
ergab leider jeweils auch +5V.

Gruß,
Henrik

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eigentlich sieht alles gut aus. Ist PD2 auf Eingang gesetzt?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erst lesen dann schreiben;)

The Receiver will override normal port
operation for the RxDn pin when enabled.

Vergiss meine Frage.

Allerdings sieht es dann fast so aus als
ob der Portpin tot ist.

Autor: Henrik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, dann wird jetzt der Lötkolben geschwungen....bzw. Morgen. Habe eben 
Ersatz bestellt.
Nochmal Danke an alle für eure Antworten.
Werde nach Tausch des Chips das Ergebnis posten... Freu mich jetzt schon 
aufs TQFP löten...
Bis dahin....

Gruß,
Henrik

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht ist ja nur der MAX hinüber; oder du hat einen Kurzschluss auf 
einen ander Pin.
Erst einmal mit einem Oskar vor und hinter dem Pegelwandler prüfen ob 
überhaupt etwas ankommt.

Autor: Andreas Vogt (tico)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Henrik schrieb:
> while( (!(UCSR1A & (1<<RXC1))) || (LSRTimeOut!=0) )
>       {//Timeout
>       _delay_ms(10);
>       LSRTimeOut--;
>       }
>
>
>     //war es ein Timeout?
>     if (LSRTimeOut==0)
>       {
>       return FALSE;

Ähm, ja, schau doch bitte nochmal genau hin. Wenn ich nicht blind bin, 
läuft diese while-Schleife immer solange, bis LSRTimeOut==0 ist. Und 
dann lieferst Du false zurück, ganz egal, ob da zwischendurch was 
empfangen wurde, oder nicht.

Gruss
Andreas

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das sehe ich auch so:

entweder: while (!0 || ....) => !0 ist true, also wird gleich in die 
Schleife gegangen.

oder: while (!1 || LSRTimeOut!=0) => !1 ist fals, also wird der zweite 
teil der oder-verknüpfung analysiert, da ist der LSRTimer aber noch >0 
=> x!=0 wird als true ausgewertet => while schleife wird ausgeführt...

ergo while wird IMMER ausgeführt, bis LSRTimeOut null ist.

Oder hab ich da jetzt einen denkfehler?

Autor: Henrik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andreas, Hallo Sebastian,
möchte mich mal so ausdrücken:
ARGLÄRGS! Da guckste Stundenlang auf den kram und siehst die olle 
Logikfalle nicht!!!

Da sach ich tausend Dank, Männer!

Sowas passiert, wenn man 'Knüppel aus dem Sack'- Logig wie:
'Entweder was empfangen OOOODEEERRR Timeout' einfach blind in den Code 
hackt... ich Idiot.


Das Leben ist wieder schön mit der korrekten logischen Verknüpfung.
Richtig muss es heißen:
while( (!(UCSR1A & (1<<RXC1))) && (LSRTimeOut!=0) )


Und kaum macht man's richtig, schon geht's!

... und ich hatte beinahe schon den Lötkolben inner Hand.

Verneige mich!

Gruß,
Henrik

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
;)

Wenn das Leben bloß immer so einfach wär... :)
So long, viel Spaß mit deiner UART!

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.