Hallo, habe ein Problem mit UART. Mein Programm soll daten via UART von einem ATmega16 zum anderen schicken. Zum testen habe ich TxD und RxD von einem µC gebrückt und will nun das dieser ein Wert herausschickt, und gleich wieder einliest. Der eingelesesne Wert soll zur Kontrolle auf einem Display angezeigt werden. Mit einer simplen Funktion habe ich bereits die Möglichkeit einen Wert, z.B. 255 zu Senden und zu empfangen, und es wird 255 auf dem Display angezeigt. Möchte ich aber mehrere Bytes verschicken verwende ich eine Funktion mit Array, die bei der Wertübergabe anscheinend immer ASCII Zeichen erwartet. Wenn ich eine 0 sende bekomme ich eine 48 zurück. Bei einer 255 bekomme ich 50 53 53. Wie muss ich den Code anpassen damit mir auf dem Display die Zahl/Buchstabe erscheint den ich losschicke? //********************************************************************** ****************************************** //Main int main (void) //Hauptprogramm { //********************************************************************** ****************************************** //zyklische Abfrage der Tasten while (1) //Endlosschleife { //beginwhile //Funktionstaste abfragen if (!(PIND & (1 << PIND7))) //PORTD7 auslesen -> wenn low Programm ausführen { display_conf(0x01); //config Befehl, Displayinhalt löschen display_conf(0x80); //config Befehl, springe in Zeile 1 auf Pos. 1 type_string ("RXD Data:"); //Ausgabe des Textes auf dem Display display_conf(0xC0); //config Befehl, springe in Zeile 2 auf Pos. 1 USART_TXD_string ("0"); //Aufrufen des USART Testprogrammes } //endif if (Interrupt==1) //wenn Interruptvariable = 1 ist { display_conf(0x01); //config Befehl, Displayinhalt löschen display_conf(0x80); //config Befehl, springe in Zeile 1 auf Pos. 1 type_string ("Ready"); //Ausgabe des Textes auf dem Display Interrupt = 0; //rücksetzen der Interruptvariable } //endif } //endwhile } //endmain //********************************************************************** ****************************************** //Testprogramm zum Empfangen von Daten via RS232 unsigned char USART_RXD (void) { //beginnUSART_RXD while ( !(UCSRA & (1<<RXC)) ); //Warten auf Datenempfang return UDR; //Rückgabe der Daten } //endUSART_RXD //********************************************************************** ****************************************** //Testprogramm zum Senden von Daten via RS232 void USART_TXD (unsigned char txd_data) { //beginnUSART_TXD while ( !(UCSRA & (1<<UDRE)) ); //Warten auf leeren transmit Puffer UDR = txd_data; //Daten in den Puffer Schreiben startet den Sendevorgang } //endUSART_TXD //********************************************************************** ****************************************** //Testprogramm zum Senden von Zeichenketten via RS232 void USART_TXD_string (const char *s) { //beginnUSART_TXD_string char string [6]; //Init des Arrays für "int_to_char" while (*s) //Solange der Inhalt des Zeigers *s nicht Null ist { //beginwhile USART_TXD (*s); //Den Inhalt von *s an Unterprogramm USART_TXD übergeben rxd_data = USART_RXD (); //Rückgabewert von USART_RXD in Register ablegen itoa (rxd_data, string, 10); //Funktion zum Tausch von Int Werten in String type_string (string); //Ausgabe der empfangenen Daten auf dem Display *s++; //ein Zeichen hochzählen } //endwhile } //endUSART_TXD_string //********************************************************************** ******************************************
>Wenn ich eine 0 sende bekomme ich eine 48 zurück. Bei einer 255 bekomme >ich 50 53 53. ist dir bewusst was diese Zeile macht?
1 | itoa (rxd_data, string, 10); //Funktion zum Tausch von Int Werten in String |
genau, sie wandelt dein Byte in eine Zeichenfolge um http://en.wikipedia.org/wiki/Itoa >Wie muss ich den Code anpassen damit mir auf dem Display die >Zahl/Buchstabe erscheint den ich losschicke?
1 | type_string (rxd_data); //Ausgabe der empfangenen Daten auf |
2 | //dem Display
|
char string [6]; kannst du dir dann sparen
1 | type_string (rxd_data + '\0'); |
so ists richtig
Hi, type_string (rxd_data); //Ausgabe der empfangenen Daten habe ich probiert, aber dann zeigt das Display überhauptnichts. Das mit itoa funktioniert merkwürdigerweise wenn ich einzelne Bytes mit USART_TXD versende/empfange, so dass ich tatsächlich auf dem Display den Dezimalwert sehe. Also sprich meine 0, oder eben alles bis 255. Das mit type_string (rxd_data + '\0'); versuche ich mal. Danke schonmal soweit, melde mich morgen ob es geklappt hat. :)
Ulli schrieb: > Das mit itoa funktioniert merkwürdigerweise Da ist nichts merkwürdiges daran. Du sendest ein Byte, du empfängst ein Byte. Von diesem Byte lässt du dir die Textrepräsentation mit itoa erstellen und gibst diese aus. End of story. Ach ja: Ein Byte kann nur Werte von 0 bis 255 annehmen. > Das mit type_string (rxd_data + '\0'); versuche ich mal. Das ist auch Quatsch. Was denkst du wohl, warum diese (von dir umgeänderte) Funktion wohl USART_TXD_string (const char *s) heißt? String! Nicht Zahl! Du sendest hier USART_TXD_string ("0"); //Aufrufen des USART Testprogrammes keine Zahl. Du sendest einen String, denn genau das ist es, was diese Funktion macht. Konzeptionell besteht für diese Funktion kein Unterschied, ob du USART_TXD_string ("schnurzelbrutz"); oder USART_TXD_string ("0"); übergibst. Beides ist einfach nur ein Text. Nur dass du als Mensch den Text "0" anders interpretierst als "schnurzelbrutz". Aber dieser Unterschied ist durch nichts gerechtfertigt. Beides sind einfach nur Texte. Wenn du eine 2-Byte Zahl übertragen musst, dann wirst du wohl den int in 2 Bytes zerlegen müssen, die beiden Bytes übertragen und die beiden empfangenen Bytes wieder zu einem int zusammensetzen müssen, ehe du dann von diesem int mittels itoa eine Textrepräsentation erzeugen kannst. Und kauf dir ein C-Buch!
>> Das mit itoa funktioniert merkwürdigerweise >Da ist nichts merkwürdiges daran. Stimmt. Schreibe gerade an etwas weiter was ich vor über nem Jahr beiseite gelegt hab, da hab ich einfach ne ganze Menge vergessen :( >Konzeptionell besteht für diese Funktion kein >Unterschied, ob du > USART_TXD_string ("schnurzelbrutz"); >oder > USART_TXD_string ("0"); >übergibst. Beides ist einfach nur ein Text. Nur dass du als Mensch den >Text "0" anders interpretierst als "schnurzelbrutz". Hi, soweit war ich inzwischen auch schon. Aber wieso zeigt mir das Display als Text nicht schnurzelburtz sondern 50 67 32 88 145.... oder so. Da brauch ich ne Funktion die ASCII in int umwandelt... und dann die itoa, oder? Gruß Ulli
>Da brauch ich ne Funktion die ASCII in int umwandelt...
bzw. ASCII in char.
Ulli schrieb: >>Da brauch ich ne Funktion die ASCII in int umwandelt... > bzw. ASCII in char. Du stocherst da wirklich übel im Nebel herum... :-/ Um zu verstehen, was du da gerade machst, solltest du dir grundlegend das Thema Zahlenformate, das Kapitel "Zeichen und Strings" im C-Buch und den ASCII-Zeichensatz ansehen. > Wenn ich eine 0 sende bekomme ich eine 48 zurück. 48dez ist eine ASCII-'0' > Bei einer 255 bekomme ich 50 53 53. 50dez ist 48dez + 2 und damit eine ASCII-'2' 55dez ist 48dez + 5 und damit eine ASCII-'5' 55dez ist 48dez + 5 und damit eine ASCII-'5' Erkennst du deine 0 und 255 wieder?
Ulli schrieb: >>übergibst. Beides ist einfach nur ein Text. Nur dass du als Mensch den >>Text "0" anders interpretierst als "schnurzelbrutz". > > Hi, soweit war ich inzwischen auch schon. Aber wieso zeigt mir das > Display als Text nicht schnurzelburtz sondern 50 67 32 88 145.... oder > so. Weil dein Display jedes Byte wieder als Buchstabe laut ASCII Code anzeigen würde, wenn du einfach nur das empfangene Byte an das Display geben würdest. Du hast ein Byte weggesendet, welches einem Buchstaben laut ASCII Code entspricht, und wenn du es wieder empfängst, lässt du dir vom Code-Zahlenwert eine Text-Ausgabe erzeugen. Was du machst, ist im Grunde nichts anderes als (wenn wir die UART Übertragungsstrecke mal weglassen)
1 | while( *s ) { |
2 | c = *s++; |
3 | itoa( c, buffer, 10 ); |
4 | type_string( buffer ); |
5 | }
|
Du gehst also einen String in s durch und lässt dir von jedem einzelnen Character im String dessen Codezahl ausgeben. Das du das Zeichen c vorher noch über den Umweg UART einmal verschickst und empfängst spielt dabei keine Rolle. Du empfängst ja das Byte wieder genauso wie du es gesendet hast. Von daher ist diese Operation aus Sicht deiner Ausgaberoutine eine NOP-Operation. > Da brauch ich ne Funktion die ASCII in int umwandelt... und dann die > itoa, oder? Was willst du eigentlich machen? Du brauchst als erstes einmal ein Verständnis dafür, dass Strings keine Zahlen sind. Auch wenn du einen String "123" hast, so ist das etwas anderes als die Zahl 123 > habe ein Problem mit UART. Dein Problem ist NICHT die UART.
Danke für die vielen hilfreichen Antworten... Das Problem war das ich die Texausgabe wiederum mit einer Funktion gemacht habe, die den Wert in ein Array gepackt hat (type_string). Wenn ich die empfangenen Bytes einzeln direkt an das Display gebe funktioniert es so wie gewünscht. Die verwirrenden hinweise das ich ne Funktion für ASCII in char brauche waren nur um hier Verwirrung zu stiften, um Zeit zu gewinnen das Problem selber zu lösen. ;) Aber mal ganz ehrlich, der Umgangston hier im Forum ist nicht sehr freundlich. Wenn jede Dumme Frage eines Anfängers gleich mit Meckerei, dummen Antworten und Buhrufen Kommentiert wird frag ich mich wozu es das hier überhaubt gibt. Meine Frage war ja eigentlich nicht so schwer: "Möchte ich mehrere Bytes verschicken verwende ich eine Funktion mit Array, die bei der Wertübergabe anscheinend immer ASCII Zeichen erwartet. Wenn ich eine 0 sende bekomme ich eine 48 zurück. Wie muss ich den Code anpassen damit mir auf dem Display die Zahl/Buchstabe erscheint den ich losschicke?" Wenn ich Profi wäre müsste ich schliesslich hier keinen Rat suchen. Wer sich unterfordert fühlt muss ja nicht Antworten. Gruß Ulli
Also lieber Ulli, ich will Dir auf Deine Frage nach den angesäuerten Antworten einmal antworten. In letzter Zeit antworte ich hier auf solche Anfängerfragen nicht mehr, einfach weil es ein schier endloses Unterfangen ist und mich letztlich auch nicht weiterbringt. Es hat sich unter Anfängern eingebürgert, ohne Kenntnisse der Grundlagen irgendwas zu programmieren. Das hier die Grundlagenkenntnisse fehlen, sieht man an dem Titel Deiner Frage als auch an Deinen Rückfragen. Dein Problem hat aber auch überhaupt nichts mit dem UART zu tun. Das aber bedeutet, das man Dir hier erstmal die Grundlagen beibringen muss. Warum machst Du das nichts selbst? Wenn Du dabei, damit ein Problem hast, würde man auch gerne helfen, aber hier muss man bei Zeitmaschinen helfen die Türangeln zu ölen und das halte ich für eine Zumutung. Und es ist zu erwarten, das man DIr noch das Gewindeschneiden, das feilen, Algebra, Infinitesimalrechnung und so weiter bis zur nötigen Quantentheorie beibringen muss und dann hätten wir es auch selbst machen können. Also lerne wie jeder Andere die Grundlagen und stelle Fragen, die sich auf die Grundlagenprobleme beziehen. Kämpf Dich durch und zeige das es Dir wichtig ist indem Du eigene Anstrengungen unternimmst. Dann hilft man hier gerne.
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.