Hallo!
Ich wollte eine Uart-Kommunikation zwischen zwei Atmega8 machen.
SIe sind verbunden:
RX----------TX
TX----------RX
Aber irgendwie wird mir auf dem Display nichts angezeigt, warum? Hier
der COde:
"Server":
Hast du schonmal geschaut, ob deine Senderoutinen überhaupt
funktionieren?
Landet was auf der TX-Leitung, wenn du senden möchtest? Empfängt der
zweite Controller irgend etwas?
Die ISR ist ziemlicher Mist. Du rufst uart_get_string mit MaxLen=1 auf,
da kannst du es auch lassen. Bau lieber um die UART einen ordentlichen
Ringbuffer, den du dann im Hauptprogramm entsprechend auslesen kannst.
Demian M. schrieb:> ISR(USART_RXC_vect){> uart_get_string(buffer, sizeof(buffer));> lcd_clear();> lcd_home();> lcd_string(buffer);> }
Das ist syntaktisch in Ordnung, programmtechnisch aber extrem unschön.
Wie lange dauert allein das Löschen und Beschreiben des LCD? Und in
welchem Abstand kommen die Zeichen über den UART?
In der ISR holst du das eine Zeichen ab, das gekommen ist und packst
es zwecks weiterer Verwendung in einen Ringpuffer. Den Rest erledigst du
dann in aller Ruhe in der Hauptschleife.
> UCSRC = (1 << UCSZ0) | (1 << UCSZ1);
Das kannst du dir ersten sparen, weil es sowieso default ist. Zweitens
versaut es dir die Baudrateneinstellung, weil URSEL fehlt.
mfg.
> uart_get_string(buffer, sizeof(buffer));
weil sizeof(buffer) immer 1 ist !
Deine Funktionen können doch nicht wissen wie lang der String ist bzw.
wissen es nur wenn die 0x00 gekommen ist. Kannst du garantieren das die
Funktionen erst aufgerufen werden wenn das Null Byte schon da war ?
> ISR(USART_RXC_vect)
wird jedesmal wenn EIN Zeichen empfangen wurde (ja 1) aufgerufen und ein
String mit der Länge EINS kann es so nicht geben weil er dann immer Leer
sein müßte um noch Platz für die Null zu haben oder es ist ein Zeichen
Drinn, dann ist es aber kein String mehr.
Also du brauchst ein Protokol mit Startbyte Paketlänge und Prüfsumme.
Ein weiterer Punkt:
ein Zeichen kommt an. Du springst in die ISR. Dort versuchst du, einen
String zu sammeln. Du wartest dazu auf '\n'. Das sendest du aber nie.
Und dein Buffer für den String ist nur 1 Zeichen groß.
Wie du das lösen kannst? Schwierige Frage. Eine Möglichkeit wäre ein
Grundkurs in Programmieren, angefangen mit "LED blinken lassen". Eine
andere Möglichkeit ist, nicht VHIT zu programmieren (vom Hirn ins
Terminal), sonder sich erst ein Ablaufdiagramm zu zeichnen. Als
praktische Lösung würde ich als erstes auf Interrupts verzichten. Das
kann im zweiten Anlauf passieren.
Und weiter oben wurde schon geschrieben: Lass mal nur den Sender laufen
und sieh dir an, was auf der TxD Leitung passiert. Wenn das deinen
Erwartungen entspricht, wirf den Empfänger an.
Georg G. schrieb:> Demian M. schrieb:>> ISR(USART_RXC_vect){>> uart_get_string(buffer, sizeof(buffer));>> lcd_clear();>> lcd_home();>> lcd_string(buffer);>> }>> Das ist syntaktisch in Ordnung
nein, ist es nicht, weil
Demian M. schrieb:> void uart_get_string(char *buffer, uint8_t MaxLen){> uint8_t NextChar;> uint8_t StringLen = 0;>> NextChar = uart_get_char();>> while(NextChar != '\n' && StringLen < MaxLen - 1) {> *buffer++=NextChar;> StringLen++;> NextChar = uart_get_char();> }> *buffer = '\0';> }
Buffer ein Pointer sein muss. Auserdem ist die schleife nie erfüllt,
wenn maxlen 1 ist.
Ändere char buffer; nach char buffer[10]
Daniel A. schrieb:> nein, ist es nicht
Ich bin nun zu faul, das durch den Compiler zu würgen. Aber es wird
vermutlich ohne Fehlermeldung übersetzt werden. Warnungen sollte man ja
ignorieren oder ausschalten (speziell als Anfänger oder bei Problemen
mit dem Code). Ich stimme zu, dass es gehobener Unfug ist.