Ich würde die UART Initialisierung vor die While-Schleife ziehen, also
diesen Abschnitt:
1 | //sprintf(str,"A:%d",UCSRA&32);
|
2 | //lcd_write1(str);
|
3 | //lcd_write1("A1");
|
4 | while(!(UCSRA&128));
|
5 |
|
6 | UCSRB |= (1<<TXEN); // UART TX einschalten
|
7 | UCSRB |= (1<<RXEN); // UART RX einschalten
|
8 | UCSRC |= (1<<URSEL)|(3<<UCSZ0); // Asynchron 8N1
|
z.B. in initUART() machen.
Und ich würde vor dem Abholen von Zeichen beim UART prüfen, ob Zeichen
vorhanden sind, also diesen Block umstellen
1 | do{
|
2 | string[i]=UDR;
|
3 | // UDR=0;
|
4 | // while (UCSRA&32);
|
5 | wait_ms (100); // Damit alle Zeichen im Buffer angekommen sind
|
6 | //lcd_write(UDR);
|
7 | i++;
|
8 | }
|
9 | while(UCSRA&128);
|
zu
1 | while(UCSRA & 128)
|
2 | {
|
3 | string[i] = UDR;
|
4 | i++;
|
5 |
|
6 | // Jetzt die Übertragungszeit für ca. 1-2 Zeichen warten
|
7 | // in der Hoffnung, dass der Sender das nächste Zeichen
|
8 | // auf den Weg gegeben hat und die Bedingung der while
|
9 | // schleife wieder erfüllt ist (Übertragung nicht zuende)
|
10 | // oder nicht erfüllt ist (alle Zeichen gesendet und empfangen)
|
11 | //
|
12 | // Die Wartezeit ist kritisch, weil bei zu langer Wartezeit
|
13 | // Zeichen verloren gehen. 100 ms wie im Originalcode halte
|
14 | // ich für deutlich zuviel. Bei 9600 Baud 8N1 liegt die
|
15 | // Übetragungszeit bei
|
16 | // 1 / 9600 Bit_pro_Sekunde / (1+8+1) Bit_pro_Zeichen
|
17 | // = ca. 1.04 ms
|
18 | //
|
19 | // Sehr stabil wird ein solcher Code mit diesem Quasi-Timeout
|
20 | // aber nicht.
|
21 |
|
22 | wait_ms (2);
|
23 | }
|
Oder besser die bereits vorhandene Funktion getchar() benutzen
1 | string[i++] = getchar();
|
Allerdings brauchst du dann auch noch einen Weg um festzustellen, ob
alle Zeichen empfangen wurden. Welcher Weg das ist, hängt vom Sender ab
z.B. feste Anzahl Zeichen oder bekanntes Endezeichen oder feste
Sendedauer...