Hallo,
habe mir hier aus dem Forum und aus dem Internet diverse Sourcecodes
angeschaut und zusammengebaut, um vom atmega16 per UART an meinen PC
einen String zu übertragen (in meinem Beispiel "Hello").
Ich bekomm aber nur <\0> oder "sinnlose" Buchstaben und Zeichen
angezeigt (im HTerm, dem Terminalprogramm das ich zum Anzeigen
verwende). Ich hab nun natürlich schon gelesen, dass die Baudrate und
F_CPU richtig gesetzt werden müssen, damit man genau solche "falsche
Zeichen" verhindern kann. Ich hab da folgenden Code verwendet:
1 | #define F_CPU 16000000UL // Systemtakt in Hz - Definition als unsigned long beachten
|
2 | #define BAUD 14400UL // Baudrate
|
3 | // Berechnungen
|
4 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
5 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
6 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
|
7 | #if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
8 | #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
|
9 | #endif
|
10 | #include <util/setbaud.h>
|
Kompiliert wird mein Programm (verwende AVRStudio6). Hier wird über
einen Parameter F_CPU sowieso nochmal gesetzt (-DF_CPU=16000000). Das
sollte also passen. Nachdem beim Compilieren auch die #error - Nachricht
nicht geworfen wird, hab ich gedacht, dass ich eigentlich die richtigen
Parameter verwende. Der Code, den ich gefunden habe ist:
1 | void uart_puts (const char *s)
|
2 | {
|
3 | do
|
4 | {
|
5 | while (!(UCSRA & (1 << UDRE)))
|
6 | ;
|
7 |
|
8 | // UDR Schreiben startet die Übertragung
|
9 | UDR = *s;
|
10 | }
|
11 | while (*s++);
|
12 | }
|
13 |
|
14 |
|
15 | void uart_init (void)
|
16 | {
|
17 | uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUD) - 1);
|
18 |
|
19 | UBRRH = (uint8_t) (ubrr>>8);
|
20 | UBRRL = (uint8_t) (ubrr);
|
21 |
|
22 | // UART Receiver und Transmitter anschalten
|
23 | // Data mode 8N1, asynchron
|
24 | UCSRB = (1 << RXEN) | (1 << TXEN);
|
25 | UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
|
26 |
|
27 | // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)
|
28 | do
|
29 | {
|
30 | UDR;
|
31 | }
|
32 | while (UCSRA & (1 << RXC));
|
33 | }
|
34 | static inline int uart_putc (const uint8_t c)
|
35 | {
|
36 | // Warten, bis UDR bereit ist für einen neuen Wert
|
37 | while (!(UCSRA & (1 << UDRE)))
|
38 | ;
|
39 |
|
40 | // UDR Schreiben startet die Übertragung
|
41 | UDR = c;
|
42 |
|
43 | return 1;
|
44 | }
|
Ich sende dann einfach über uart_puts("Hello").
Ich bin nun ein bisschen ratlos, warum trotz richtiger Baudrate (welche
ich auch am Terminalprogramm so gewählt habe, nämlich 14400) und der
F_CPU (welche ja auch lt. Compiler 16000000 sein sollte (mein ATMega16
hängt auch an einem 16MHz Quarz)) die Zeichen falsch übertragen werden.
Kann mir jemand einen Denkanstoß geben?
LG Christian