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.
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.
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...
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;
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.
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.
Mit einem 4MHz-Quarz bekommst du keine 9600Bd, sondern 10000Bd. Und das
bedeutet, dass dein Empfänger nicht richtig synchronisieren kann. ->
Baudratenquarz verwenden!
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
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!
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?
@ 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
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.
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
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
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.