mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART - Receive-Transmit -Problem


Autor: Parvis S. (parvis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe folgendes Problem:

Ich sende Zeichen vom Computer zum ATMEGA8 und der uC sendet diese 
gleich zurueck (via Interrupt). Das klappt soweit ganz gut, ausser das 
der uC manchmal die Zeichen nicht sofort wieder zuruecksendet, sondern 
ich erst wieder Zeichen senden muss, welche er mir dann mit den 
vorherigen Zeichen zurueckgibt.
Meine Vermutung ist, dass die Zeichen manchmal im Transmit Shift 
Register haengen bleiben (wie gross ist das eigentlich?).
Wenn ich nun nach dem Einlesen ins UDR einige Zeit warte (=mehr als 100 
Zyklen ... genau weiss ich das Momentan nict), dann tritt das Problem 
nicht auf. Ich verwende einen Baudratenquarz mit 7372800Hz und das 
STK500-Board. Programmierung in ASM.

Kann mir da jemand vielleicht weiterhelfen?

Der Code ist in gekuerzter Fassung folgender (volle Version im Anhang):
.include "m8def.inc"
.def temp1     = r16         ; allgemeines temp Register
.def temp2     = r17         ;
.def temp3     = r18         ;
.def temp4     = r19         ;
.def temp5     = r20 

.equ F_CPU = 7372800                          ; Systemtakt in Hz
.equ BAUD  = 115200                            ; Baudrate
.equ SENSORS = 6
 
; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif

.org 0x000
  rjmp init
 
.org URXCaddr
    rjmp int_rxc

;---------------------------------------------------------------------------------
; Start des Programms

init:
   ; Stackpointer initialisieren   

      ldi temp1, LOW(RAMEND)      ; LOW-Byte der obersten RAM-Adresse
      out SPL, temp1
      ldi temp1, HIGH(RAMEND)     ; HIGH-Byte der obersten RAM-Adresse
      out SPH, temp1
;----------------------------------------------------------------------------------
    ; Baudrate einstellen 
    ldi     temp1, HIGH(UBRR_VAL)
    out     UBRRH, temp1
    ldi     temp1, LOW(UBRR_VAL)
    out     UBRRL, temp1 
    ; Frame-Format: 8 Bit 
    ldi     temp1, (1<<URSEL)|(3<<UCSZ0)
    out     UCSRC, temp1 
    sbi     UCSRB,TXEN                  ; TX aktivieren
    sbi     UCSRB, RXEN                 ; RX (Empfang) aktivieren
    sbi     UCSRB, RXCIE                ; Interrupt bei Empfang 
    sei                                 ; Interrupts global aktivieren
;----------------------------------------------------------------------------------

main:
rjmp main;

;--- Receive Data -----------------------------------------------------------------
int_rxc:
    push    temp1                       ; temp1 auf dem Stack sichern
    in      temp1, sreg                 ; SREG sichern
    push    temp1

    in      temp1, UDR                  ; UART Daten lesen
    rcall serout_byte;
  
    pop     temp1
    out     sreg, temp1                 ; SREG wiederherstellen
    pop     temp1                       ; temp1 wiederherstellen
reti

;----- Fuer RS232 -------------------------------------------------------------------------

serout_byte:
  push temp3;
  in temp3, SREG
  push temp3
  serout_byte_wait:
      sbis    UCSRA,UDRE ; Warten bis UDR bereit ist
  rjmp serout_byte_wait;
  out UDR, temp1;

  pop temp3
  out SREG, temp3
  pop temp3
ret

Ich danke schonmal im voraus fuer jede Hilfe und Anregung.

Gruss,

Parvis

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Das Datenregister UDR ist gepuffert. D.h. 'sbis    UCSRA,UDRE' testet ob 
der Puffer frei ist, nicht ob das Byte gesendet wurde. Wenn du sicher 
sein willt, das das Byte gesendet wurde musst du 'TXC' abfragen ->
'sbis    UCSRA,TXC'.

MfG Spess

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn UDRE gesetzt ist, kann man auch in das Transmit-Register schreiben. 
Der Schreibvorgang auf UDR triggert in jedem Fall die Ausgabe. 
Schlechtestenfalls kommen halt 2 Bytes direkt nacheinander. Dabei kann 
es aber nicht zu Aussetzern kommen. Ich vermute das Problem eher auf 
PC-Seite und dessen Pufferbehandlung. Wenn Du kannst, prüfen den TXD-Pin 
mal mit einem Oszilloskop. Bin fast 100%-ig sicher, daß der Controller 
immer sendet.

Autor: Parvis S. (parvis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 wrote:
> Hi
>
> Das Datenregister UDR ist gepuffert. D.h. 'sbis    UCSRA,UDRE' testet ob
> der Puffer frei ist, nicht ob das Byte gesendet wurde. Wenn du sicher
> sein willt, das das Byte gesendet wurde musst du 'TXC' abfragen ->
> 'sbis    UCSRA,TXC'.

Ich habe das mal ausprobiert und direkt nach dem schreiben in UDR 'sbis 
UCSRA,TXC' als Schleife eingesetzt. Gleiches Resultat (wenn ich das 
testweise davor mache, dann bleibt er in eine Endlosschleife haengen)! 
Oder wo wuerde man die Abfrage sonst hinmachen?

Gruss,

Parvis

Autor: Parvis S. (parvis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn UDRE gesetzt ist, kann man auch in das Transmit-Register schreiben.
> Der Schreibvorgang auf UDR triggert in jedem Fall die Ausgabe.
> Schlechtestenfalls kommen halt 2 Bytes direkt nacheinander. Dabei kann
> es aber nicht zu Aussetzern kommen. Ich vermute das Problem eher auf
> PC-Seite und dessen Pufferbehandlung. Wenn Du kannst, prüfen den TXD-Pin
> mal mit einem Oszilloskop. Bin fast 100%-ig sicher, daß der Controller
> immer sendet.
Meinst Du, dass das im Empfangs-Puffer vom Computer ist oder der 
Computer es noch nicht angenommen und es deshalb beim uC haengen 
bleibt?? Dann duerfte aber eigentlich der TXC im UCSRA nicht geloescht 
werden, oder? Leider habe ich gerade kein Oszi zur Hand. Gebe es denn 
noch eine andere Moeglichkeit das zu testen??? Welche Variablen koennte 
ich denn noch testen? Eins ist sicher, der uC empfaengt alle Daten (mit 
via LCD-Display nachgeprueft) und bleibt auch soweit in keiner Schleife 
haengen.

Gruss,

PArvis

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.