Forum: Compiler & IDEs String mit UART Senden/Empfangen -> code macht ASCII aus char


von Ulli (Gast)


Lesenswert?

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


//********************************************************************** 
******************************************

von Helfer (Gast)


Lesenswert?

>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

von Helfer (Gast)


Lesenswert?

1
type_string (rxd_data + '\0');
so ists richtig

von Ulli (Gast)


Lesenswert?

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. :)

von Karl H. (kbuchegg)


Lesenswert?

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!

von Ulli (Gast)


Lesenswert?

>> 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

von Ulli (Gast)


Lesenswert?

>Da brauch ich ne Funktion die ASCII in int umwandelt...

bzw. ASCII in char.

von kurz (Gast)


Lesenswert?

Echt ASCII in char?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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.

von Ulli (Gast)


Lesenswert?

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

von Naja (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.