Forum: Mikrocontroller und Digitale Elektronik UART sendet nur wirres zeug


von Tobias D. (Gast)


Lesenswert?

Hallo,
ich hab ein problem und zwar das der uart nur wirres zeug sendet. ich 
habe die init schon 100mal^^ umgeändert oder mich durch totorials 
gelesen.
villt könnt ihr mir ja helfen.
hier mein code:

#define F_CPU 4000000      //Takt 4Mhz
#define BAUD 9600

#include <avr/io.h>
#include <util/delay.h>      //Headerfile für Zeitschleife
#include <stdio.h>

int wait()
{
_delay_ms(300);
return 0;
}


int main ()
{

DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xff;

//UART init

UBRRH = 0b00000000;    //Kommunikationsgeschwindikeit bestimmen
UBRRL = 0b00011001;    //25
UCSRC = 0b10000110;        //8Bit
UCSRB = 0b00001000;    //UART senden

    while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich
    {
    }


while (1)
{
UDR = 'x';
}      //schreibt das Zeichen x auf die Schnittstelle

return 0;
}




danke schonmal.

von Karl H. (kbuchegg)


Lesenswert?

Tobias D. schrieb:

> #define F_CPU 4000000      //Takt 4Mhz

Fang damit an, das zu überprüfen.

In 95% aller Fälle von 'wirrem' Zeug, hast du hier den Übeltäter

>
> UBRRH = 0b00000000;    //Kommunikationsgeschwindikeit bestimmen
> UBRRL = 0b00011001;    //25
> UCSRC = 0b10000110;        //8Bit
> UCSRB = 0b00001000;    //UART senden

Das ist ganz schlecht geschrieben. Damit machst du es anderen nur 
unnötig schwer, kurz mal drüberzuschauen. Kein Mensch hat Lust, Bits 
auseinanderzupfriemeln um zu sehen, was du da alles gesetzt hast.

von Frederik K. (n0ll4k)


Lesenswert?

Nimmst du nen internen oder externen Quarz?

Ansonsten wäre Controller und so nett zu wissen.

Und die Binärsschreibweise solltest du dir schnellstmöglich wieder 
abgewöhnen. Da weisst du nach nem Tag auch nicht mehr was das bedeuten 
soll..

edit
Zu langsam...

von Fabian (Gast)


Lesenswert?

Du wartest nicht bevor das X gesendet wurde, sondern startest die 
Übertragung immer neu. Das kann nicht klappen.

Außerdem:

UBRRH = 0b00000000;    //Kommunikationsgeschwindikeit bestimmen
UBRRL = 0b00011001;    // 25

wieso schreibst Du nicht: ???

UBRR = 25;

von Rainer M. (excogitator)


Lesenswert?

> Außerdem:
>
> UBRRH = 0b00000000;    //Kommunikationsgeschwindikeit bestimmen
> UBRRL = 0b00011001;    // 25
>
> wieso schreibst Du nicht: ???
>
> UBRR = 25;

Vielelicht weil 0b00011001 != 25 ist :)

von Karl H. (kbuchegg)


Lesenswert?

Rainer M. schrieb:
>> Außerdem:
>>
>> UBRRH = 0b00000000;    //Kommunikationsgeschwindikeit bestimmen
>> UBRRL = 0b00011001;    // 25
>>
>> wieso schreibst Du nicht: ???
>>
>> UBRR = 25;
>
> Vielelicht weil 0b00011001 != 25 ist :)

Doch ist es.
Allerdings hab ich auch keine Lust, jetzt nachzurechnen ob die 25 bei 
der gegebenen F_CPU und BAUD Rate korrekt sind. Sowas kann der Compiler 
auch ausrechnen, also soll er das auch machen. Die dazu nötige Formel 
ist hinlänglich bekannt und sollte sich auch in jedem Tutorial finden 
lassen.

Ich weiß zwar nicht 100% was passiert, wenn man der UART bei laufender 
Übertragung ein neues Zeichen ins UDR stellt. Da das Senderegister aber 
gepuffert ist (über welchen µC reden wir eigentlich?), denke ich nicht, 
dass das beschriebene Verhalten darauf zurückzuführen ist, auch wenn es 
sich beim Nichtwarten ganz klar um einen Fehler im Programm handelt. Der 
würde sich IMHO eher so auswirken, dass Zeichen komplett auf der 
Gegenstelle fehlen, was sich mangels Zeichenvariation aber momentan 
nicht feststellen lässt.

von Markus (Gast)


Lesenswert?

Wenn 0b00011001 nicht 25 ist, was soll es denn dann sein?

von Rainer M. (excogitator)


Lesenswert?

Ihr habt ja recht...hab mich um eins verzählt.

von Johnny B. (johnnyb)


Lesenswert?

Mit einem Oszi könnte man auch nachschauen wie lange die Bits 
tatsächlich sind um zu checken, wie es mit der Baudrate ungefähr 
aussieht.

von Tobias D. (Gast)


Lesenswert?

Ich danke euch für die Ratschläge.
Also ich nutze einen Mega16 mit einem externen Quarz, 4Mhz.

ich habe meinen code noch mal überarbeitet. leider funktioniert er immer 
noch nicht. ich weiß auch nicht, worans liegen könnte. für den uart 
benutze ich einen USB-TTL umsetzer.
hier der link dazu:

http://www.virtualvillage.de/pc-usb-auf-rs232-rs485-ttl-uart-konverter-adapter-006401-041.html?utm_source=googlebase&utm_medium=shcomp

TXD, RXD, VCC und GND habe ich verbunden und den treiber installiert.
als terminalprogramm nutze ich HTERM.

Die Kommunikationsgeschwindigkeit habe ich berechnet und zur sicherheit 
noch mal im datenblatt nachgelesen.

Takt:4Mhz
Boud:9600
= 25 //das simmt also.

hier noch mal der überarbeitete code:

______________________________________________________________________ 
__

#define F_CPU 4000000      //Takt 4Mhz
#define BAUD 9600

#include <avr/io.h>
#include <util/delay.h>      //Headerfile für Zeitschleife
#include <stdio.h>

int wait()
{
_delay_ms(300);
return 0;
}


int main ()
{

DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xff;

//UART init

UCSRB |=(1<<TXEN);     //UART als Sender
UCSRB &=~(1<<UCSZ2);    //8Bit Frame
UCSRC |=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);   //8BIT Frame
UCSRC &=~(1<<UMSEL)|(1<<UPM0)|(1<<UPM1)|(1<<USBS);
//asynchron, disablet Parity, 1 Stopbit
UBRRH = 0;
UBRRL = 25; //Kommunikationsgeschwindigkeit 25



  while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich
    {
    }


while (1)
{
wait();
UDR = 'x';
}
//schreibt das Zeichen x auf die Schnittstelle

return 0;
}


danke.

von Helmut -. (dc3yc)


Lesenswert?

Mit einem 4MHz-Quarz bekommst du keine 9600Bd, sondern 10000Bd. Und das 
bedeutet, dass dein Empfänger nicht richtig synchronisieren kann. -> 
Baudratenquarz verwenden!

von Tobias D. (Gast)


Lesenswert?

allerdeings wenn ich UBBRH beschreibe mit 0; löscht sich UCSRC wieder. 
ist das nur ein simulationsfehler?

von spess53 (Gast)


Lesenswert?

Hi

>Mit einem 4MHz-Quarz bekommst du keine 9600Bd, sondern 10000Bd. Und das

Blödsinn. Die reale Baudrate ist mit UBRR= 25 9615,4Bd. Der Fehler liegt 
bei 0.2%.

MfG Spess

von dumdidumm (Gast)


Lesenswert?

Helmut -dc3yc schrieb:
> Und das
> bedeutet, dass dein Empfänger nicht richtig synchronisieren kann.

Stichwort Empfänger: Wast hast du für einen Empfänger? TTL-Level oder 
"normales" RS-232 ? RS-422? Je nach dem Pegelwandler nicht vergessen! 
Sonst kriegt du wenn überhaupt, auch nur Müll!

von Tobias D. (Gast)


Lesenswert?

ich nutze den TTL-Level...

von Karl H. (kbuchegg)


Lesenswert?

Tobias D. schrieb:
> allerdeings wenn ich UBBRH beschreibe mit 0; löscht sich UCSRC wieder.
> ist das nur ein simulationsfehler?

Das hat mich auch mal eine Weile beschäftigt.
Setze zuerst UBRRH und erst dann UCSRC

(Die beiden Register teilen sich eine Adresse, umgeschaltet wird mit dem 
Flag URSEL beim Schreiben)

> Also ich nutze einen Mega16 mit einem externen Quarz, 4Mhz.

Hast du kontrolliert, ob der auch benutzt wird?

von Tobias D. (Gast)


Lesenswert?

wie kann ich das denn kontrollieren? bei den fuse bits is der externe 
eingestellt.

von Tobias D. (Gast)


Lesenswert?

könnte das auch evtl. an win7 von meinem rechner liegen, dass das nicht 
funzt?^^

von g457 (Gast)


Lesenswert?

> wie kann ich das denn kontrollieren? bei den fuse bits is der externe
> eingestellt.

Vertrauen ist gut, Kontrolle besser. Pseudocode:
1
#include <util/delay.h>
2
int main()
3
{
4
   STATUS_LED_SET_OUTPUT();
5
   while (1)
6
   {
7
      _delay_ms(500);
8
      STATUS_LED_SET_ON();
9
      _delay_ms(500);
10
      STATUS_LED_SET_OFF();
11
   }
12
}

von Tobias D. (Gast)


Lesenswert?

ohh man ich hab einfach nicht die leitungen gekreuzt -.-' das hätte mir 
aber mal jemand von euch sagen können :P ;)

von Falk B. (falk)


Lesenswert?

@  Tobias D. (Gast)

>ohh man ich hab einfach nicht die leitungen gekreuzt -.-' das hätte mir
>aber mal jemand von euch sagen können :P ;)

Du hättest auch einfach mal wie die Millionen anderen UART-Patienten vor 
dir bissel lesen können.

http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART

MFG
Falk

von Karl H. (kbuchegg)


Lesenswert?

Tobias D. schrieb:
> ohh man ich hab einfach nicht die leitungen gekreuzt -.-' das hätte mir
> aber mal jemand von euch sagen können :P ;)

Das ist unlogisch.
Bei falsch gekreuzten Leitungen kommt auf der Gegenseite .... gar nichts 
an.
Wenn du daher wirres Zeugs empfängst, hast du noch ein Hardwareproblem.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Das ist unlogisch.

Das dachte ich mir erst auch. Daher hielt ich die Geschichte mit den 
gekreuzten Leitungen zunächst für eine Ausrede. ;-)

> Bei falsch gekreuzten Leitungen kommt auf der Gegenseite .... gar nichts
> an.

Ja, bei RS232-Pegeln ist das so. Aber er hat einen USB-TTL-Converter. 
Wie der sich bei offenen Eingängen verhält ... keine Ahnung. Aber 
eigentlich sollte der zumindest Pull-Ups in den Leitungen haben, um 
"still" zu bleiben, solange kein Signal anliegt.

Gruß,

Frank

von Michael R. (mexman) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
..
> Das ist unlogisch.
> Bei falsch gekreuzten Leitungen kommt auf der Gegenseite .... gar nichts
> an.

Er hast ja nicht "falsch" gekreuzt sondern richtig!

Und da kommt sehr wohl gelegentlich Muell an..... aber das ist ja wohl 
das erste nachdem man schaut ;-)

Problem geloest.... prima


Gruss

Michael

von Karl H. (kbuchegg)


Lesenswert?

Michael Roek-ramirez schrieb:
> Karl heinz Buchegger schrieb:
> ..
>> Das ist unlogisch.
>> Bei falsch gekreuzten Leitungen kommt auf der Gegenseite .... gar nichts
>> an.
>
> Er hast ja nicht "falsch" gekreuzt sondern richtig!


Misverständnis.

Als seine Kreuzung noch falsch war, hat die Gegenstelle etwas empfangen, 
obwohl das technisch nicht möglich ist, weil niemand auf dieser Leitung 
etwas sendet.   -> offene Leitung oder dergleichen.

Erst nachdem er die Kreuzung richtig gestellt hat, stammt das empfangene 
tatsächlich vom Sender. Das da auch manchmal wirres Zeug dabei ist, ist 
eine andere Geschichte.

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.