Hallo, Obwohl ähnliche Beiträge schon recht viele rumgeistern komme ich mit der Programmierung der UART nicht weiter. Ich habe diese früher bereits erfolgreich mit AVR Studio 4 verwendet für ein Debug-Log am PC (serielles Terminal). Nun benötige ich das selbe mit Atmel Studio 7. Mein erstes Problem ist, dass hier irgendwie der OnBoard Oszillator des STK500 nicht mehr konfiguriert werden kann. Ist das korrekt oder irgendwie möglich? Habe also mit einem Oszi die derzeitige Frequenz am XT1 Pin gemessen (ca. 3.84MHZ). Diese auch in meiner Software konfiguriert. Auch mit einem separaten Quarz (4MHZ) hatte ich keinen Erfolg. Habe auch das mit Oszi kontrolliert. Jumper waren korrekt gesetzt. Takt stimmte. Das eigentliche Problem ist nun, dass ich per UART am seriellen Terminal nur Blödsinn bekomme. Langsam bin ich am verzweifeln. Die Terminaleinstellungen scheinen nicht das Problem zu sein. Hab das mehrmals gecheckt. Habe auch verschiedenste Baudraten probiert. Hoffe jemand hat einen Tipp. Der relevante Code: #include <avr/io.h> /* UART-Init: Berechnung des Wertes für das Baudratenregister aus Taktrate und gewünschter Baudrate */ #ifndef F_CPU /* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann F_CPU im Makefile definiert werden, eine nochmalige Definition hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch #ifndef/#endif Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio verwendet wird und dort eine andere, nicht zur Hardware passende Taktrate eingestellt ist: Dann wird die folgende Definition nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) von AVRStudio - daher Ausgabe einer Warnung falls F_CPU noch nicht definiert: */ #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000" #define F_CPU 4000000UL // Systemtakt in Hz - Definition als unsigned long beachten // Ohne ergeben sich unten Fehler in der Berechnung #endif #define BAUD 300UL // Baudrate // Berechnungen #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler. #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010)) #error Systematischer Fehler der Baudrate groesser 1% und damit zu hoch! #endif void uart_init(void) { UBRRH = UBRR_VAL >> 8; UBRRL = UBRR_VAL & 0xFF; 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))) {} UDR = 'a'; } return 0; } Lg Lukas
Da ist kein DDRx drin, also: Port Pin nicht auf Ausgang gesetzt.
1 | #define BAUD 300UL // Baudrate
|
So niedrige Baudrate kann auch zu Überlaufen im Teiler führen, denn der hat ja nur eine begrenzte Anzahl Bits. Habe ich aber jetzt nicht nachgerechnet ob das hier der Fall ist.
Habe wie gesagt alle Baudraten durchprobiert. Kein Erfolg. Habe nun als Einstellung 1200 und Clock 4Mhz verwendet. Im Anhang das Ergebnis auf dem Terminal. Habe nun wie von dir geschrieben DDRD0 (RXD) auf Eingang und DDRD1 (TXD) auf Ausgang gesetzt. Dies bewirkt keine Änderung. Ich denke das muss man auch nicht explicit machen. Danke Lg, Lukas
Benutze einen ATMega16. Die Eistellung des Sw-Clock des Stk500 über Atmel Studio habe ich mittlerweile gefunden. Hat aber nichts geändert. Was meinst du mit dem Taktteiler? Baudratenregister habe ich gesetzt. Code siehe im ersten Beitrag. Sg
Kann es sein, dass der verwendete USB-RS232 Adapter die Probleme verursacht? Das Flashen des Controllers funktioniert aber einwandfrei darüber.
lakiluk schrieb: > Die > Terminaleinstellungen scheinen nicht das Problem zu sein. Hi, mit Hyperterminal hatte ich Probs. Mit Teraterm nicht. Lokales Echo -> Haken setzen. Vom Prog. her: Also Polling Schleife für URDE ist drin. (Vergess ich immer. Nicht mit Interrupt.) ciao gustav
Ein Oszillogramm des TxD Pins würde evtl. auch weiter helfen die effektive Baudrate zu bestimmen. Und nein, hier wird nicht über den Takt der Datenübertragung vom Programmer zum Chip geschrieben, die Du wohl im Atmel-Studio gefunden hast. Es geht um die Frequenz, mit der Dein Mikrocontroller arbeitet. Ist das nicht der Wert, den Du als F_CPU vorgibst, kann aus der Berechnung nur Quark rauskommen. (BTW : gibt der Compiler die Warnung aus, dass F_CPU gesetzt werden musste ?) Dazu wichtig sind die sogenannten Fuse-Bits und je nach diesen, der angeschlossene Quarz bzw. Resonator.
Hi, noch ein ASM-Schnipsel. War immer der Meinung, dass man URSEL nicht anders ansprechen könnte. Das ist aber schon im Bit-Code des Registers drin, so dass diese Zeile überflüssig wird. ciao gustav
Danke für die Antworten! Ein Oszi kann ich leider nicht bieten vom TxD, da ich nur ein analoges mein Eigen nenne ;) Die Takteinstellung (welche ich mittlerweile gefunden habe) die ich meinte, ist die Einstellung des Onboard-Clockgenerators des STK500. Beim AVR-Studio 4 war dies noch etwas einfacher zu finden. Das ist aber nicht das Problem denke ich. Habe nun den Takt des Boards auf 3,686MHZ gestellt. Dieser Takt wird an den uC vom Board weitergegeben. Im C-Code habe ich natürlich die F_CPU nun auch auf diesen Takt definiert. Jedoch ohne Erfolg. Immer noch falsche Zeichen. Terminalprogramme habe ich auch schon mehrere versucht. Also die Einstellung stimmt sicher. Immer selbes Ergebnis. Was mir nun aufgefallen ist, früher hatte ich die UART am AT90s8515 verwendet (der hat keine FUSE-Bits). Daher nehme ich an, dass ich diese falsch gesetzt habe?! Es soll der externe Takt des STK500 verwendet werden. Die Fuse-Bits waren auf int. Oszillator gestellt. Habe sie nun auf ext. Clock geändert (siehe Anhang). Leider bekomme ich immer noch defekte Zeichen. Diese Einstellung sollte aber korrekt sein oder? Am STK500 steckt nicht nur ein Quarz, sondern es wird wirklich der komplette Takt generiert. Sg Lukas
Lass mal eine LED blinken. 500ms an, 500ms aus (mit einfachen _delay_ms(500)). Und dann vergleichst du mit einer Stoppuhr, ob die Zeit tatsächlich stimmt.
Danke @stefanus! Beim Include der avr/delay.h ist mir aufgefallen, dass der Include nach Setzen von F_CPU geschehen muss. Gleiches gilt für den Include der io.h... Somit funktioniert nun alles :) Danke nochmal an alle! Lg Lukas
F_CPU gehört nicht in den Quelltext, sondern in die Projektkonfiguration als "Definition" bzw. in das Makefile, damit der Compiler so aufgerufen wird: avr-gcc -DF_CPU=16000000 ...
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.