Hallo, ich verwende einen ATmega8 und möchte gerne ein Zeichen über die
Serielleschnittstelle an einen Terminal(PC) senden.
Doch es tut sich nichts.
#include <avr/io.h>
#define F_CPU 3686400L
#define BAUD 9600L
#define UBRR_VAL = ((3686400/(9600*16))-1)
void uart_init(void) {
UBRRH = 0x00;
UBRRL = 0x17;
UCSRB |= (1<<TXEN); // UART TX einschalten
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
}
int main(void) {
while(1){
while (!(UCSRA & (1<<UDRE))) // warten bis Senden moeglich
{
UDR = 'x';
}
UDR = 'x';
}
}
Wäre super, wenn mir jemand helfen könnte, danke.
1 | while (!(UCSRA & (1<<UDRE))) // warten bis Senden moeglich |
da fehlt ein Semikolon
die geschwungene Klammer befindet sich eine Zeile darunter, müsste doch passen oder?
Sepp Horst schrieb: > die geschwungene Klammer befindet sich eine Zeile darunter, müsste doch > passen oder? Nein. Du schreibst doch selbst im Kommentar "warten bis Senden möglich". Es ist also sinnlos, während das Wartens ständig etwas ins UDR zu schreiben.
Ok, danke. Bekomme jedoch noch falsche Zeichen im Terminal. Das müsste doch an einer falschen Baudrate liegen? Habe im Terminal und im Programm auf 9600 baud, 1 Stopp - Bit gestellt, was könnte ich noch falsch gemacht haben?
Sepp Horst schrieb: > #define F_CPU 3686400L > #define BAUD 9600L > #define UBRR_VAL = ((3686400/(9600*16))-1) Warum definierst du eine L-Konstante, wenn du die zwei Zeilen später gar nicht verwendest. Und wozu wird UBRR_VAL berechnet? Wenn du deinem Code nicht traust, kannst du besser den Ablauf im Simulator verfolgen (z.B. die UART Initialisierung), anstatt irgendwelche magischen Zahlen im Quellcode zu verteilen. Sepp Horst schrieb: > die geschwungene Klammer befindet sich eine Zeile darunter, müsste doch > passen oder? Überleg mal, was in der While-Schleife passieren soll?
>Ok, danke. Bekomme jedoch noch falsche Zeichen im Terminal. Das müsste >doch an einer falschen Baudrate liegen? Habe im Terminal und im Programm >auf 9600 baud, 1 Stopp - Bit gestellt, was könnte ich noch falsch >gemacht haben? Dein uC läuft mit falschem Takt. Vermutlich 1MHz intern RC. Du musst die Fuses auf Crystal Osc umstellen. UND BLOSS NICHT AUF EXTERN CLOCK!
Habe bei Fuses auf: Ext. Crystal/Resonator High Freq.; Start-up time: 16K CK + 64 ms gestellt. Ist das Richtig?
#include <avr/io.h>
#define F_CPU 3686400
#define BAUD 9600
//#define UBRR_VAL = ((3686400/(9600*16))-1)
void uart_init(void) {
UBRRH = 0x00;
UBRRL = 0x17;
UCSRB |= (1<<TXEN); // UART TX einschalten
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
}
int main(void) {
uart_init();
while(1){
while (!(UCSRA & (1<<UDRE))) { // warten bis Senden moeglich
}
UDR = 'x';
}
}
Sepp Horst schrieb: > Habe bei Fuses auf: Ext. Crystal/Resonator High Freq.; Start-up time: > 16K CK + 64 ms gestellt. Ist das Richtig? Und hat es geklappt? (Du hast doch einen Quarz drauf? Hoffe ich zumindest) Ich kann nur wieder auf die Checkliste verweisen. Dort ist auch enthalten, wie man überprüfen kann, ob der µC jetzt tatsächlich mit der am Quarz aufgedruckten Frequenz arbeitet. http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
Habe den Quarz laut SDK - 500 Handbuch gejumpert und die Fuses eingestellt. Es hat sich nichts verbessert, es werden noch immer fast kreisrunde Zeichen statt x ausgegeben.
Sepp Horst schrieb: > Habe den Quarz laut SDK - 500 Handbuch gejumpert und die Fuses > eingestellt. Es hat sich nichts verbessert, es werden noch immer fast > kreisrunde Zeichen statt x ausgegeben. Zum 35.ten mal: Hast du KONROLLIERT, ob dein µC mit der am Quarz aufgedruckten Frequenz läüft oder hast du das nicht? Es ist uninteressant was du wo reingesteckt hast und welche Fuse du wo umgestellt hast. Du musst KONTROLLIEREN ob dein µc mit der gewünschten Taktrate läuft. Vertrauen ist gut, Kontrolle ist besser. Zu mehr als 98% sind deine Symptome auf eine falsche Taktrate zurückzuführen. Möglich, dass du zu den verbleibenden 2% gehörst. Aber solange du nicht definitiv die 98% ausschliessen kannst (und zwar aufgrund von Messungen), ist das erst mal die Arbeitshypothese Nummero Uno.
Sepp Horst schrieb: > Hab den Quarz mit Hilfe des Testprogrammes und einer LED getestet, er > funktioniert. F_CPU war auf 3696400 gestellt? Blinken alleine ist zu wenig. Stimmt das Timing auch? Am besten mit einer Stoppuhr 20 mal aufblinken der LED abstoppen. Die gemessene Zeit sollte ziemlich genau 40 Sekunden betragen - im Rahmen der Genauigkeit einer Handstoppung. (Es gibt nur die beiden Möglichkeiten entweder die Taktfrequenz im µC stimmt nicht oder das Terminalprogramm ist auf eine andere Baudrate eingestellt. Wenn die beiden Dinge korrekt sind und die RS232 über das Jumperfeld richtig angestöpselt wurde (da kannst du kaum einen Fehler machen), dann MUSS die RS232 soweit funktioneren. Terminal am PC zuerst hochfahren und laufen lassen. Dann erst den µC einschalten, wobei die Kabelverbindung schon bestehen muss. Stimmt das Timing, dann muss das auf Anhieb klappen.
Hab da Timing gestoppt, ein Zustand am LED dauert jeweils eine Sekunde. Hab nun versucht das Terminalprogramm zu starten, anschließend wurde die Verbindung mit den richtigen Einstellungen hergestellt und schlussendlich habe ich den µC eingeschaltet. Resultat --> es funktioniert (also lag es an der Reihenfolge von Connection starten und µC einschalten) Vielen Dank!
Gut.
Was du dir merken musst: Du kannst dich nicht mit dem Empfänger in eine
laufende ununterbrochene Übertragung einschalten. Der Empfänger ist
darauf angewiesen, dass der Sender immer wieder mal eine kleine Pause in
der Übertragung einlegt, damit er sich zu 100% sicher auf den Anfang
eines Zeichens synchronisieren kann. Ansonsten bekommt der Empfänger Bit
um Bit vorgesetzt und kann nicht feststellen, bei welchem Bit ein
Zeichen anfängt.
int main(void) {
uart_init();
while(1){
while (!(UCSRA & (1<<UDRE))) { // warten bis Senden moeglich
}
UDR = 'x';
_delay_ms( 10 ); // <--------
}
}
hätte den gleichen Zweck erfüllt.
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.