Hallo! Ich habe ein Evaluation Board 2.0 bei Pollin angeschafft und mit einem ATmega16 bestückt. Danach (unter zuhilfnahme des Datenblatte und des UART Tutorials) eine kleine Initialisierungsprozedur für das UART geschrieben. Das Hauptprogramm solln nur zwei Dinge erledigen, immmer wieder auf UDRE warten und dann das Zeichen 'x' ins UDR-Register schreiben. Beim Debuggen wird allerdings nur zweimal ins UDR geschrieben, danach wird endlos auf UDRE gewartet. Wenn ich das Programm auf den Controller übertrage wird trotzdem kein einziges Byte übertragen. Die Übertragung über den MAX 232 von TI ist getestet, indem der PC mit dem Eval-Board verbunden wurde, dann die Masse, RxD, TxD von der 40-pol. Stiftleiste bzw. von Jumper 1 + 2 des Eval-Boards auf eine Wandlerplatine für RS232-Pegel (ebenfalls Pollin) verbuden wurden. Anschliessend konnte man mit Bray's Terminal Daten vom PC übers Eval-Board über die Wandlerplatine auf eine zweiten PC an dessen Bray-Terminal verschicken. Statt des 8 MHZ Quarzes habe ich einen mit 7372800 Hz ins Eval-Board eingebaut und die Fuse über das AVR Studio mit AVRProg auf "Ext XTAL, medium frequency" umgestellt. Da auf dem E-Board zwei LED's sind habe ich zunächst ein kleines Blinky-Programm getippt und laufen lassen. War kein Problem. Jetzt möchte ich die UART benutzen und bin, trotz Zahlreich gelesener Threads und Code-Examples, schon an der Übertragung eines einzelnen Charcters gescheitert. Die Datei mit meinem Quellcode (etwas ausführlicher als nötig, ...) ist im Anhang. Kann jemand den Fehler erkennen und etwas dazu sagen? Gruß Markus
Hi@All! Es gab einige Downloads, aber keine Antwort, kann daraus schliessen das noch jemand ratlos ist? Selbst habe ich inzwischen den Quellcode leicht geändert, und an einen ATtiny2313 angepasst, der passt ebenfalls ins Evaluation-Board. Da der ATtiny auch nicht sendet und die Simulation bei dem auch nicht geht, bleibt mir wohl nur noch mit dem AVR Studio von SP2 nach SP4 und beim WinAVR von 20060421 ebenalls auf eine höhere Version zu wechseln. Ich hab' an einigen Stellen allerdings auch schlechtes vom SP4 gehört, das gleiche gilt auch für den aktuellsten WinAVR 20070101. Deshalb meine Frage: Konnte jemand das Problem auf einem der Controller Typen bei sich nachvollziehen, oder des Code mit erfolgt ausführen? Vielleicht hilft es mir weiter, wenn er/sie mit die Versionsnummer seines AVR Studios und des WinAVR schreibt. Danke! Markus
Probier mal dieses Programm auf dem Mega16 aus:
1 | #ifndef F_CPU
|
2 | #define F_CPU 7372800UL
|
3 | #endif
|
4 | |
5 | #include <avr/io.h> |
6 | |
7 | |
8 | void InitUart( unsigned int Baud ) |
9 | {
|
10 | UCSRB |= (1<<TXEN) | (1<<RXEN); |
11 | UCSRC |= (1<<URSEL)| (1<<USBS) | (3<<UCSZ0); |
12 | |
13 | Baud = F_CPU / (Baud * 16L) - 1; |
14 | |
15 | UBRRH = (unsigned char)( Baud >> 8 ); |
16 | UBRRL = (unsigned char)Baud; |
17 | }
|
18 | |
19 | void uart_putc( const char c ) |
20 | {
|
21 | while( !( UCSRA & (1<<UDRE) ) ) |
22 | ;
|
23 | UDR = c; |
24 | }
|
25 | |
26 | int main() |
27 | {
|
28 | InitUart( 4800U ); |
29 | |
30 | while( 1 ) { |
31 | uart_putc( 'X' ); |
32 | }
|
33 | }
|
Wenns damit nicht klappt, hast du ein Hardware-Problem. In dem Fall tippe ich mal darauf, dass das RS232 Kabel nicht richtig gekreuzt ist.
@ Markus C. The Data Register Empty (UDRE) Flag indicates whether the transmit buffer is ready to receive new data. This bit is set when the transmit buffer is empty, and cleared when the transmit buffer contains data to be transmitted that has not yet been moved into the Shift Register. For compatibility with future devices, always write this bit to zero when writing the UCSRA Register. (lt. Atmega16(L) Datenblatt) Mach das letztere mal in deiner uart-init-Routine, insbesondere weil der Initialwert 1 ist (lt. AVR-GCC-Tutorial).
Danke für die Unterstützung! Da Ihr euch für mein Problem(chen) interssiert habt, gilt das vermutlich auch für die Lösung. Es gibt eine gute Nachricht, und eine Lösung, die ich so nicht erwartet hatte. Ein Hardwareproblem gibt's gottlob nicht, der Controller ist jetzt auf Sendung. Nachdem KHB's Code erfolgreich ausgeführt wurde habe ich mich noch auf Fehlersuche begeben ... Wenn ich in der Initialisierungsroutine folgendes UCSRC |= (1<<URSEL) | (0<<USBS); // stopBit UCSRC |= (1<<URSEL) | (1<<UCSZ0); // characterSize UCSRC |= (1<<URSEL) | (1<<UCSZ1); // characterSize durch UCSRC |= (1<<URSEL) | (0<<USBS) | (1<<UCSZ0) | (1<<UCSZ1); ersetzte, dann funktioniert die UART - Das leuchtet mir im Augenblick nicht ein. Das (1<<URSEL) entscheidet dabei ob das zu schreibende Byte ins UBRRH oder in UCSRC geschrieben wird. Was den Simulator im AVR Studio betrifft ... der bleibt bei beiden Varianten in der Sendeschleife hängen und wartet, nachdem er 2 Bytes ins UDR geschrieben hat endlos auf UDRE. Vermtulich nimmt er an, das sowohl das Schieberegister als auch UDR mit Daten belegt sind, die noch nicht gesendet wurden. Evtl. probiert ich morgen noch im Code etwas einzubauen um die Warteschleife zu unterbrechen .. ein Delay und dann irgendwie das UDRE wieder auf "1" setzen, damit der Simulator annehmen kann das UDR ist seinen Inhalt ans Schieberegister losgeworden. @Stefan Habe das mal probiert, und in der Initialisierungsprozedur UCSRC = 0x00 eingetragen ... ein paar Zeilen später, bei der initialisierung des UBRRH setzt der Simulator des AVR Studio UDRE-Bit eigenmächtig wieder auf "1"!?!? Die schreiben da ausserdem etwas von Kompatibilität zu kommenden Controllertypen ... . Lohnt sich bestimmt da mal im Hinterkopf zu speichern! Vorerst bleib ich beim ATmega16 :-)) Besten Dank! Markus
Ist zwar für eine Atmega8. Aber deutlich kürzer als deins. Du musst die Bits nicht alle Null (z.b. UCSRB |= (0<<UCSZ2);) setzen. Glaub die sind von vornherein Null. #include <avr/io.h> #include <avr/iom8.h> #ifndef F_CPU #define F_CPU 3686400 #endif int main(void) { UCSRB |= ((1 << RXEN) | (1 << TXEN)); UCSRC |= ((1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0)); UBRRH = 0; UBRRL = 23; while (1) { UDR = 'x'; while (!(UCSRA & (1<<UDRE))) { } } return (0); }
OK! Die Länge des Code hat sich beim "Trail and Error" ergeben - War erstmal nicht entscheident, das Einkürzen kommt dann beim "Aufräumen". Trotzdem Danke. Hat jemand eine Erklärung dafür: Wenn ich in der Initialisierungsroutine folgendes UCSRC |= (1<<URSEL) | (0<<USBS); // stopBit UCSRC |= (1<<URSEL) | (1<<UCSZ0); // characterSize UCSRC |= (1<<URSEL) | (1<<UCSZ1); // characterSize durch UCSRC |= (1<<URSEL) | (0<<USBS) | (1<<UCSZ0) | (1<<UCSZ1); ersetzte funktioniert der Code - Bin immer noch der Ansicht das ist beides das Gleiche. Gruß! PS: Wo find' ich denn hier eine Beschreibung der Features (Syntaxhighlighting)?
Von der Sprachsyntax her das gleiche. Nur, weiss man, wie Atmel die Initialisierung im µC tatsächlich macht? Du musst bedenken, dass du ein Hardwareregister (UCSRC) beschreibst und daraufhin eine dir/mir unbekannte "Auswertelogik" bestimmte Pfade in der Hardware entsprechend den Konfigurationsbits umbiegt. Alle Bits auf einen Schlag setzen, wird (ohne Begründung) in den Beispielen in den Atmel Datenblättern auch gemacht.
Das bringt mich auf folgenden Gedanken, bei der etwas zu auführlichen Variante wir das UCSRC bei der Zuweisung eigentlich nur mit einer Bitmaske ODER-Verknüpft, denke das können die bei ATMEL. Vielleicht gibt es ein HW-Problem, wenn man das dreimal hintereinander macht (Timing). Da in der Regel vermutlich alle die kurze Variante nehmen ... . EGAL!
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.