UART sendet nur wirres zeug

Gast #1840327
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.
#1840330
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.
Gast #1840333
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;
#1840374
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.
Gast #1841242
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.
#1841362
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?
Gast #1841672
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
}
Moderator Persönliche Seite #1842650
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
#1842669
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren