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;
> Außerdem: > > UBRRH = 0b00000000; //Kommunikationsgeschwindikeit bestimmen > UBRRL = 0b00011001; // 25 > > wieso schreibst Du nicht: ??? > > UBRR = 25; Vielelicht weil 0b00011001 != 25 ist :)
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.
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.
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!
allerdeings wenn ich UBBRH beschreibe mit 0; löscht sich UCSRC wieder. ist das nur ein simulationsfehler?
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?
wie kann ich das denn kontrollieren? bei den fuse bits is der externe eingestellt.
könnte das auch evtl. an win7 von meinem rechner liegen, dass das nicht funzt?^^
> 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 | } |
ohh man ich hab einfach nicht die leitungen gekreuzt -.-' das hätte mir aber mal jemand von euch sagen können :P ;)
@ 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.