Forum: Mikrocontroller und Digitale Elektronik UART sendet falsche Zeichen / Angepaßter Tutorial Code


von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Versuche gerade über die UART zu senden, mit Mega48 aber irgenwei kommt 
da nur folgendes raus:
½åëW5<25><23>½åëW5<25><23>½åëW5<25><23>½åëW5<25><23>
Als HEX:
BD E5 EB 57 35 19 17 BD E5 EB 57 35 19 17 BD E5 EB 57 35 19 17 BD E5 EB 
57 35 19 17

Quarz ist 20Mhz, CHKDIV/8 ist aus.
1
.include "m48def.inc"
2
3
.equ F_CPU = 20000000                            ; Systemtakt in Hz
4
.equ BAUD  = 2400                               ; Baudrate
5
 
6
; Berechnungen
7
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
8
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
9
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
10
 
11
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
12
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
13
.endif
14
15
.def temp = r17
16
.def zeichen=r16
17
18
19
  ldi     temp, LOW(RAMEND)
20
    out     SPL, temp
21
    ldi     temp, HIGH(RAMEND)
22
    out     SPH, temp
23
 
24
    ; Baudrate einstellen
25
 
26
    ldi     temp, HIGH(UBRR_VAL)
27
    sts     UBRR0H, temp
28
    ldi     temp, LOW(UBRR_VAL)
29
    sts     UBRR0L, temp
30
 
31
    ; UCSR0C Standard = Parity: none, Stopbit: 1, Frame-Format: 8 Bit
32
33
   ; TX aktivieren
34
   lds temp, UCSR0B
35
  ori temp, (1<<TXEN0)
36
    sts UCSR0B,temp                  
37
38
loop:
39
    ldi     zeichen, 'T'
40
    rcall   serout                      ; Unterprogramm aufrufen
41
    ldi     zeichen, 'e'
42
    rcall   serout                      ; Unterprogramm aufrufen
43
    ldi     zeichen, 's'
44
    rcall   serout                      ; ...
45
    ldi     zeichen, 't'
46
    rcall   serout
47
    ldi     zeichen, '!'
48
    rcall   serout
49
    ldi     zeichen, '\r'
50
    rcall   serout
51
    ldi     zeichen, '\n'
52
    rcall   serout
53
    rjmp    loop
54
 
55
serout:
56
  push zeichen
57
  serout_wait:
58
    lds zeichen, UCSR0A
59
      sbrs zeichen, UDRE0              ; Warten bis UDR für das nächste
60
                                       ; Byte bereit ist
61
    rjmp serout_wait
62
  pop zeichen
63
    sts     UDR0, zeichen
64
    ret

Bin etwas ratlos... eigentlich sollte das doch so funktionieren... 
loopback am MAX zum PC funktioniert zumindest anstandslos.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Habe jezt noch versucht das Frameformat explizit zu setzen mit:
; UCSR0C Standard = Parity: none, Stopbit: 1, Frame-Format: 8 Bit
  ldi temp, (1<<UCSZ01) | (1<<UCSZ02)
  sts UCSR0C, temp
Außerdem den ganze PortD als Ausgang
  ldi temp, 0xFF
  out DDRD, temp

Leider immer noch keine Besserung :-\

von NiceGuy (Gast)


Lesenswert?

Moin moin.

Der PC empfängt offensichtlich deutlich mehr Zeichen als Du sendest. Das 
deutet auf eine zu geringe Baudrate beim AVR hin. Kann es sein, dass das 
Teil nicht mit dem externen Quarz läuft, sondern mit 8 MHz intern?

Dein nachgebesserter Code scheint mir auch noch eine Macke zu haben:
UCSZ02 steckt in UCSR0B, und UCSZ01/00 in UCSR0C.

Gruß, Reiner.

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.