Forum: Mikrocontroller und Digitale Elektronik AVR-Tutorial: UART, nur Müll kommt an


von F. K. (freddy436)


Angehängte Dateien:

Lesenswert?

Hallo,

erstmal danke für das tolle Tutorial, bisher hat alles wunderbar
geklapt.
Jetzt wollte ich mich mit dem UART beschäftigen. Dabei habe ich
allerdings einige Probleme. Leider konnte mir die Suche bisher auch noch
nicht helfen.

Das ganze ist auf einem Bread Board aufgebaut, ich Benutze einen ATmega8
(ATMEGA 8-16 DIP). Der Aufbau ist soweit genau wie im Tutorial
beschrieben, mit der kleinen Ausnahme das ich einen normalen Quarz
verwende
(http://www.reichelt.de/?SID=X;ACTION=3;LA=4;GROUP=B41;GROUPID=3173;ARTICLE=2449;START=0;SORT=artnr;OFFSET=16).
Den habe ich wie im Datenblatt auf Seite 25 beschrieben mit 22pF
Kondensatoren angeschlossen.

Als Programm verwende ich das erste Beispiel (uart-mega8.asm) von
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART

Ich habe schon diverse Taktgeber Kombinationen versucht (externer Quarz,
sowohl den internen 1Mhz und 4Mhz).

Als Verbindung zum Computer habe ich sowohl einen normalen Seriellen
Anschluss als auch ein USB Adapter verwendet, jedoch mit dem selben
Ergebnis.

Am Computer kommt nur jede Menge müll an, das beste Ergebnis habe ich
bisher mit
.equ CLOCK = 1000000 (interner Taktgeber, alle FUSES im
Auslieferungszustand)
.equ BAUD = 4800
gemacht. Am Computer habe ich entsprechend 4800,8,N,1 eingestellt, damit
bekam ich jedoch wiederum nur Müll. Ich habe es dann auf 9600 gestellt
(nur am PC, nicht im Programm), dann habe ich schon einige "Test!"s
empfangen, jedoch immer noch mit einer menge Müll (siehe Anhang).

Ich weis nicht woran es noch liegen könnte.

Desweiteren ist mir ein kleiner Fehler im aufgefallen, dort findet man
diese Zeile:
UBRR = Taktfrequenz / 16 * Baudrate - 1
Die Klammern fehlen.

von Uwe (Gast)


Lesenswert?

Hi!
Wenn du nach UBRR den
(Wert deines Quarzes(in Hz)/(16 x gewünschte Baudrate)-1)
lädst, sollte es auch klappen.

MFG Uwe

von F. K. (freddy436)


Lesenswert?

habe diese zwei Zeilen hinzugefügt:
ldi temp, UBRRVAL
out UBRR, temp

Resultat:
error: Undefined symbol: UBRR

von Dennis (Gast)


Lesenswert?

Beim ATMega8 muß das so aussehen:

  ldi r16,25 ;9600 Baud @ 4MHz
  out UBRRL,r16
  ldi r16,0
  out UBRRH,r16

Das Register heißt UBBRL und nicht UBRR.

von Dennis (Gast)


Lesenswert?

Außerdem: Nimm auf jeden Fall einen EXTERNEN Quarz, der interne 
Oszillator funktioniert manchmal, manchmal aber auch nicht. Mit einem 
externen Quarz, am besten einem Baudratenquarz, bist Du auf jeden Fall 
auf der sicheren Seite.

von F. K. (freddy436)


Lesenswert?

Mit den 4 Befehlen habe ich wieder ein ähnliches Phänomen, am Computer 
habe ich 9600 eingestellt => nur Müll.
Mit 19200 kann man wiederum einige verstümmelte Test lesen.
Ich hab es sowohl mit dem internen als auch mit dem externen getestet.

Ich habe hier noch zwei andere Atmels, einen mega162 und einen kleinen 
tiny2313, ich werde mal gucken ob ich die zum laufen bekomme.

Die ganze Geschichte mit den Oszilatoren ist ziemliches Neuland für 
mich, das es mit dem Internen öfters zu Problemen kommt habe ich hier 
schon mehrfach gelesen, aber woran erkenne ich den einen 
"Baudratenquarz"?

von Uwe (Gast)


Lesenswert?

Hi!
Du musst natürlich den Wert für UBRR(L/H) immer mit deiner verwendeten 
Quarzfreq. neu berechnen und eintragen. Nochwas, wenn der Wert für 
UBRR(H/L) <255 ist, reicht es UBRRL zu beschreiben.

MFG Uwe

von F. K. (freddy436)


Lesenswert?

Genau das mach ich ja eigentlich auch, mit 4Mhz Quarz=>
4M/(16*9600)-1 = 25

ldi r16, 25
out UBRRL,r16
ldi r16, 0
out UBRRH,r16

von F. K. (freddy436)


Lesenswert?

habe es jetzt mal mit dem mega162 versucht, mit dem internen war nix zu 
machen, mit dem externen 4Mhz läuft es jetzt auch mit der richtigen 
Baudrate, aber es kommt immer noch eine menge Müll an.

von Dennis (Gast)


Lesenswert?

Hast Du auch die Fuses geändert? Einfach nur einen externen Quarz 
hinhängen bringt nämlich nix, Du mußt auch die Fuses ändern.
Ich habe auch einen 4MHz-Quarz bei 9600 Baud, die 25 ist schon 
richtig...

von Dennis (Gast)


Lesenswert?

Hier is mal ein total simples Programm, mit dem ich teste, ob die 
USART-Hardware funktioniert. Sendet nach einem Reset "Ben!" per USART 
und macht danach nichts mehr.
für 9600 Baud @ 4 MHz
Gerade nochmal probiert, funktioniert.

;Sendet "Ben!"
.include "m8def.inc"

.def usart_send = r17

.org 0x000  rjmp reset      ; /*Interrupts:
.org 0x001  reti
.org 0x002  reti
.org 0x003  reti
.org 0x004  reti
.org 0x005  reti
.org 0x006  reti
.org 0x007  reti
.org 0x008  reti
.org 0x009  reti
.org 0x00a  reti
.org 0x00b  reti ;rjmp Usart_RXC    ; USART RX-Complete
.org 0x00c  reti
.org 0x00d  reti ;rjmp Usart_TXC    ; USART TX-Complete
.org 0x00e  reti
.org 0x00f  reti
.org 0x010  reti
.org 0x011  reti        ; Interrupts*/

reset:

  ldi r16,low(RAMEND)  ; Stack
  out SPL, r16
  ldi r16, high(ramend)
  out SPH, r16

  ldi R16, 25      ; UBBR:9600 Baud @ 4MHz
  out UBRRL, r16
  ldi r16,0
  out UBRRH, r16

  ldi r16,(1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1)
  out  UCSRC, r16
  ldi r16, (1<<TXEN) ; | (1<<RXEN)
  out UCSRB, r16

  sei            ;Enable Interrupts

  ;Sendet Ben!
  ldi usart_send,'B'
  rcall SEND
  ldi usart_send,'e'
  rcall SEND
  ldi usart_send,'n'
  rcall SEND
  ldi usart_send,'!'
  rcall SEND
  ldi usart_send,13 ;Carriage Return (CR)
  rcall SEND
  ldi usart_send,10 ;LineFeed (LF
  rcall SEND

MAIN:
  rjmp MAIN

SEND:
  sbis UCSRA,UDRE
  rjmp SEND
  out UDR,usart_send
  ret

von F. K. (freddy436)


Lesenswert?

Danke, es läuft jetzt, die Fuses, etc. waren alle richtig gesetzt.

Das Problem lag an der Spannung, ich habe hier eigentlich eine kleine 
konstant Spannungsquelle wie im Tutorial beschrieben aufgebaut, beim 
Messen kam 5,04V raus.
Ich habe durch Zufall die Spannung auf 4V runtergesetzt, damit läuft es 
jetzt wunderbar. Obwohl laut Datenblatt eigentlich 4,5V - 5,5V möglich 
sein sollen.

von Martin (Gast)


Lesenswert?

@ Frederik:

Meinst Du Vcc vom Atmega8 ? Mit richtiger Spannung funktioniert es 
jetzt?

Ich habe nämlich bei mir genau das gleiche Problem: Uart sendet und ich 
empfange nur kryptische Zeichen mit dem Terminal Programm.

von F. K. (freddy436)


Lesenswert?

Ich habe das komplette Breadboard auf 4V gesetzt, nicht nur Vcc/AVcc vom 
mega8, auch Vcc vom meinem MAX3232.

Der MAX lief allerdings auch problemlos auf 5V (per loopback getestet).

Probier es einfach mal aus die Spannung nen bisschen runterzuregeln. Ich 
werde nachher auch nochmal genau gucken wo der Problem Punkt liegt.

von Martin (Gast)


Lesenswert?

Also ich hab als Spannugn ~5V auf µC und am MAX232. Trotzdem 
funktioniert das Senden nicht richtig.

Mein Problem liegt darin:

Wenn ich z.B. sende "aaaabbbbcccc" dann kommt auf dem Terminal-Prog raus 
";;;;9999====". Also alles irgendwie "verschoben". Die Anzahl der 
Zeichen stimmt schon, nur empfange ich das gesendete Zeichen nicht.

Vielleicht liegt es an der Übertragungsart?

von Dennis (Gast)


Lesenswert?

5,04 V dürfen aber eigentlich nicht das Problem sein. Ich hab die MAX232 
CPE von Reichelt, funktionieren wunderbar.

von Martin (Gast)


Lesenswert?

Ich hab auch mit dem Oszi gemessen. Am Ausgang des MAX232 kommen -10 und 
+10V Pegel heraus. Also das stimmt schon alles. Kann sein das die 
Ursache im HyperTeminal Programm liegt, dass ich das falsch eingestellt 
habe? Weil gesendet wird ja was, das sehe ich auch mit dem Oszi.

von Karl heinz B. (kbucheg)


Lesenswert?

Hmm.
Auch aus dem Vergleich der Bitmuster werde ich nicht schlauer
1
a        a        a        b        b        b        c        c
2
61       61       61       62       62       62       63       63
3
01010001 01010001 01010001 01010010 01010010 01010010 01010011 01010011
4
5
;        ;        ;        9        9        9        =        =
6
3B       3B       3B       39       39       39       3D       3D
7
00111011 00111011 00111011 00111001 00111001 00111001 00111101 00111101

Das ergibt irgendwie nicht wirklich was. Da ist keine Verschiebung
oder sowas zu erkennen. Auch die doppelte Baudrate scheidet
aus, weil ja die Anzahl der gesendeten Zeichen mit der Anzahl
der empfangenen Zeichen übereinstimmt.

Trotzdem würde ich mal auf ein Timing Problem tippen.
Wenn beide Schnittstellen (µC und PC) auf 8N1 eingestellt
sind, ist eine nicht funkionierende RS232 eigentlich
praktisch immer eine Timing-Sache.

Die Sache mit der Versorgungsspannung weiter oben, mag
ich kaum glauben. Ich kann mir beim besten Willen nicht
vorstellen, wie die die Übertragung beeinflussen kann.
D.h. Ich könnte mir schon was vorstellen: interner
Oszillator als Taktgeber, aber der wurde ja explizit
ausgeschlossen.




von Martin (Gast)


Lesenswert?

Also ich hab µC sowie PC auf 8N1 Übertragung @ 9600 Baud eingestellt. 
Der Controller ist ein Atmega8 @ 4Mhz.

Die Anzahl der Empfangenen Zeichen stimmt mit der Anzahl der Gesendeten 
überein, jedoch ist das übertragene Zeichen meist ein anderes.

Benutze ein externen Quarz, Fuses: CKSEL=1110 SUT=10 (müsste alles 
richtig sein soweit...)

Ich poste hier mal mein .c Prog vielleicht kann man da den Fehler 
finden:
Danke schonmal!


#includes.....

#define F_CPU 4000000UL
#define BAUD 9600UL
#define UBRR_BAUD ((F_CPU)/(16*(BAUD))-1)


// ************************************* UART_EINSTELLUNGEN

void uart_init(void)
{
  UCSRB |= (1<<TXEN) | (1<<RXEN);  // UART TX, RX einschalten
  UCSRC |= (1<<URSEL) | (3<<UCSZ0); // Asynchron 8N1

  // UART Baudrateregister setzen
  UBRRL = (uint8_t) UBRR_BAUD;
  UBRRH = (uint8_t) (UBRR_BAUD>>8);
}

// ************************************* UART_SENDE_FUNKTIONEN

int uart_putc(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)));    // warten bis Senden moeglich
  UDR = c;
  return 0;
}

void uart_puts(char *str)
{
    while (*str)
  {
    uart_putc(*str++);
  }
}


// ************************************* HAUPTPROGRAMM

int main(void)
{

uart_init();


  while( 1 )
  {
  uart_puts("AAAABB");
  }

return 0;
}

von Karl heinz B. (kbucheg)


Lesenswert?

>   // UART Baudrateregister setzen
>   UBRRL = (uint8_t) UBRR_BAUD;
>   UBRRH = (uint8_t) (UBRR_BAUD>>8);

Zuerst das Highbyte setzen und dann das LowByte.
Mit dem Setzen des LowBytes werden beide in die
tatsächliche Verarbeitung übernommen.
Obwohl: Das High Byte ist doch bei deinen Werten sowieso 0.

Egal: Einen Versuch ist es wert.

von Dennis (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Martin,

hab Dein Programm gerade bei mir laufen lassen, bei mir funktioniert es. 
Der Fehler liegt also woanders.
Hab Dir mal das benutze Makefile mit angehängt, hab allerdings nichts 
daran geändert.
Viel Glück bei der Fehlersuche!

von Martin (Gast)


Lesenswert?

Dein Tip hab ich mal umgesetzt mir der Reihenfolge, aber daran liegts 
auch nicht. Ich check morgen mal die Hardware vom MAX232, vielleicht 
spinnt der.

Aber dass 5V Pegel in -10V und 0V in 10 gewandelt werden ist schon 
richtig oder?

von F. K. (freddy436)


Lesenswert?

Also bei mir spinnt das Ding ab 4,7/4,8V, zu Weihnachten gibst mal nen 
anständiges Labornetzteil ;).

Den MAX kannst du eigentlich recht einfach testen, schliss einfach die 
TX/RX Pins den du normalerweise an den µC anschließen würdest kurz, und 
dann tipp nen bisschen im hyperterminal rum, du solltest alles was du 
eingetippt hast genauso wieder angezeigt bekommen.

von F. K. (freddy436)


Angehängte Dateien:

Lesenswert?

Im Anhang hab ich ein leicht verändertes Programm aus dem Tutorial, 
sollte einfach alles was rein kommt wieder raus schicken, bei mir klappt 
es auch.

von Martin (Gast)


Lesenswert?

Ich hab mal nachgemessen:

Da wo die Kondensatoren angeschlossen sind an dem MAX232 ist eine 
Wechselspannung anliegend, von ca. 190 kHz. Da frag ich mich doch was 
das soll.... Vom Netzteil kommt nur 5V rein und die ist sehr glatt. Der 
Receive Kanal funktioniert nicht, aber der wird ja auch beim Senden 
nicht benutzt, also ist das keine Lösung für mein Problem.

von Martin (Gast)


Lesenswert?

So ich hab das Problem gelöst. Der GND Pin hatte ich falsch 
angeschlossen (schäm)das war aber nicht nur das Problem, sondern auf 
dem Laptop funktioniert die Ausgabe nicht, auf einem normalen PC aber 
schon. Verkehrte Welt...

von F. K. (freddy436)


Lesenswert?

Ich habe das Problem gefunden.

Ich habe den 22µF/63V Elko zwischen dem GND/VCC Pin des MAX 232 ICs 
durch einen 100nF Keramik Kondensator ersetzt. Jetzt klappt es auch 
wunderbar mit 5V. Sobald ich den Kondensator auch nur über 5cm Kabel 
anschließe klappt es schon nicht mehr, wirklich nur wenn man den 
Kondensator direkt an die zwei Pins klemmt.

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.