Forum: Mikrocontroller und Digitale Elektronik C Problem mit Umwandlung


von Beni Zaiser (Gast)


Lesenswert?

Hallo Leute,
ich hab einen ATMEGA 8535 und ein Problem mit dem USART!
Wenn ich im C-Programm folgendes reinschreib:
usart_transmit(4);
dann kommt im Hyperterminal ein schwarzes Karo an.
--> Das ist der ASCII Code für die Zahl 4.
Wenn ich im C-Programm folgendes reinschreib:
usart_transmit("4");   1)
Dann kommt im Hyperterminal auch eine 4 an.
So hätt ichs gern.

In meinem Programmablauf möchte ich nun eine
Zahl, die in ticks steht und größer als 256 ist
über usart_transmit senden.

Quellcode: 2)
unsigned char *p = (unsigend char*) & ticks;
unsigned char low_byte = p[0];
unsigned char high_byte = p[1];
usart_transmit(low_byte);
usart_tranmist(high_byte);

Wenn ich das jetzt so ins C-Programm schreib,
kommen im Hyperterminal wieder diese ASCII Steuer-
zeichen an. Ich möchte aber gerne die Zahlen sehen.

Frage:
Kann man irgendwie den Code 2) so umformen, dass
er dem Code 1) entspricht???? sodass ich im HyperTerminal
auch die Zahlen empfange???

Ich brauch dringend eure Hilfe, komm einfahc nicht mehr
weiter....

gruß
beni

von crazy horse (Gast)


Lesenswert?

"dann kommt im Hyperterminal ein schwarzes Karo an.
--> Das ist der ASCII Code für die Zahl 4."
Nö, das ist kein ASCII.
"Wenn ich im C-Programm folgendes reinschreib:
usart_transmit("4");   1)
Dann kommt im Hyperterminal auch eine 4 an.
So hätt ichs gern."
Das ist dann ASCII.

Programmiertechnisch ist das am einfachsten mit printf() zu erledigen,
kannst es aber auch "zu Fuss" machen, braucht dann wesentlich weniger
Code. Dazu die Zahl in bis zu 5 einzelne chars aufteilen (10.000er,
1000er, 100er, 10er, 1er), zu jedem Wert noch 0x30 addieren, fertig.

von Beni Zaiser (Gast)


Lesenswert?

Vieeeelen Dank für die Antwort.
Aber ich bin in C net so fit!
Wenn das so wenig Code ist,
könntest du mir den vielleicht noch ins Forum schreiben???
Also wie ich die Zahl in 5 einzelne Chars aufteile.

Wär nett,
danke

gruß
bnei

von crazy horse (Gast)


Lesenswert?

#include <stdio.h>
.
.
.

printf ("\r\n%u",deine_zahl);

//sendet deine_Zahl als ASCII-String mit vorangestelltem Zeilenvorschub
(\r\n\) als Trennzeichen. Formatsteuerung %u gibt an, das das
Argument als vorzeichenlose Dezimalzahl ausgegeben wird.

von Beni Zaiser (Gast)


Lesenswert?

Hä?
muss das dann so heißen:
unsigned char *p = (unsigned char *) & ticks;
unsigned char low_byte = p[0];
unsigned char high_byte = p[1];
usart_transmit(printf ("\r\n%u",low_byte)));
usart_transmit(printf ("\r\n%u",high_byte)));

geht aber net,
beim ersten Aufruf kommen nur Leerzeichen und
bei jedem weiteren kommen nur Häuschen an...

gruß
beni

von Fiffi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Beni,

im Anhang liegt eine Assemblerdatei für AVR-GCC (WinAVR) die eine
Binärzahl in ein ASCII-Zeichen umwandelt.

Ein kleines Beispiel:

char buf[4];

bin2ascii8(1, buf, 1);      // String "1"
bin2ascii8(1, buf, 2);      // String "01"
bin2ascii8(199, buf, 3);      // String "199"


Gruß

Fiffi

von Peter Fleury (Gast)


Lesenswert?

Für die Umwandlung von int nach String gibt es beim WinAVR fertige
Routinen ! Siehe auf AVR-Libc Manual

#include <stdlib.h>


    char buffer[7];
    int  num=134;

    /* convert interger into string */
    itoa( num , buffer, 10);

-> Konvertiert Wert 137 in String "137"

von Fiffi (Gast)


Lesenswert?

Hallo Peter,

>Für die Umwandlung von int nach String gibt es beim WinAVR fertige
>Routinen ! Siehe auf AVR-Libc Manual

Das weiß ich ...


1. itoa verbracht ~160 Byte Code, meine Routine verbraucht ~62 Byte
Code.

2. itoa arbeitet mit "int" und überschreibt immer 4 Zeichen in dem
Puffer. Meine Routine arbeitet zwar nur mit "char", dafür kann man
die Breite aber einstellen ...


Meiner Meinung nach ist itoa nicht oft zu gebrachen ...

Gruß

Fiffi

von Beni Zaiser (Gast)


Lesenswert?

Erstmal vielen Dank für eure Hilfe.
@ Fiffi:
Ich kann doch in mein C Programm keine Assembler Datei miteinbinden.
Der Compiler bringt nur Fehler!!!!

Deswegen hab ich die zweite Methode mit itoa versucht:
Da kommt aber nie das raus, was ich gern hät:
Wenn ich die Zahl 134 versenden möchte:

  char buffer[7];
  unsigned int  ticks=134;
  usart_transmit(itoa( ticks2, buffer, 10));

Im HyperTerminal kommt aber nur 0 an!!!

Wenn ich die Zahl 3 versenden möchte:

  char buffer[7];
  unsigned int  ticks=3;
  usart_transmit(itoa( ticks, buffer, 10));

kommt im HyperTerminal auch nur ne 0 an!!!

Wenn ich diesen Code eingebe:

  unsigned int ticks = 5321;
  char buffer[7];
  unsigned char *p = (unsigned char *) & ticks;
  unsigned char low_byte = p[0];
  unsigned char high_byte = p[1];
  usart_transmit(itoa( low_byte , buffer, 10));
  usart_transmit(itoa( high_byte , buffer, 10));

Kommen im Hyperterminal: HH an!!!

Was mach ich denn immer noch falsch???
Ach ja, die Zahl die ich senden möchte beträgt maximal 65536!
Mit usart_transmit kann ich nur ein Byte senden. Deswegen
die Aufteilung im letzten Quellcode!
Um wieder auf 5321 zu kommen muss ich dann am Computer diese Formel
ausrechnen: 5321 = erste_Zahl + zweite_Zahl * 256

Ich bitte nochmals um Hilfe
gruß
beni

von crazy horse (Gast)


Lesenswert?

wenn du noch nicht so fit bist, dann nimm doch erstmal die einfachste
Variante!

unsigned int ticks = 5321;
printf ("%u",ticks);

Ja, es gibt codeeffizientere Methoden, aber was soll das hier??

von Beni Zaiser (Gast)


Lesenswert?

Hallo crazy horse,
also ich hab jetzt deine einfachste Methode benützt.
-->
  unsigned int ticks = 5;
  usart_transmit(printf ("%u",ticks));

Ich hab den Code auf ein Taster gelegt, sodass wenn ich diesen drücke,
die 5 gesendet wird.
Beim ersten drücken kommt im Hyperterminal ein Leerzeichen an. Bei
jedem weiteren Drücken ein Häuschen!!!!!!!!
keine Spur von einer 5. An was liegt das? Was muss ich anders machen?

   ach ja hier noch die routine usart_transmit(){
   void usart_transmit( unsigned char data ) {
   /* Wait for empty transmit buffer */
   while ( !( UCSRA & (1<<UDRE)) )
   ;
   /* Put data into buffer, sends the data */
   UDR = data;
   }

gruß beni

von Josef (Gast)


Lesenswert?

Würde einmal Ascii Zeichen schicken !

unsigned int ticks = 5;
usart_transmit(printf ("%u",ticks + 0x30));

Josef

von Peter Fleury (Gast)


Lesenswert?

>Ich kann doch in mein C Programm keine Assembler Datei miteinbinden.
Ja aber der Linker kann assemblierte Assembler Daten zusammenfügen

>Deswegen hab ich die zweite Methode mit itoa versucht:
>Da kommt aber nie das raus, was ich gern hät:
>Wenn ich die Zahl 134 versenden möchte:
Bitte schaue in der Doku nach wie die Parameter der itoa() Funktion
lauten.

>Mit usart_transmit kann ich nur ein Byte senden.

Du musst eben eine Schleife programieren:

char *p = buffer;

while ( *p ){
   usart_transmit(*p++)
}

von crazy horse (Gast)


Lesenswert?

Meine Herren, das kann doch alles nicht wahr sein.
Vergiss doch erstmal dein usart_transmit(), printf() benutzt die
Routine putchar() für die Ausgabe.

von Beni Zaiser (Gast)


Lesenswert?

@Josef:
Das + 0x30 macht keinen Unterschied. Es kommt das gleiche im
HyperTerminal an!

@crazy horse:
das heißt also, dass dieser Ausdruck:
#include <stdio.h>

unsigned int ticks = 5321;
printf ("%u",ticks);

ALLEINE, ohne irgendwelches usart_transmit die Zahl 5321 ans
HyperTerminal sendet????
Kann nicht sein, hab ich nämlich schon ausprobiert, kommt gar nix an.
(Kein Leerzeichen, nichts)

Es gibt hier glaub ich missverständnisse:
Frage:
Kann mir jemand den Code sagen, der eine Zahl in einen String umwandelt
und dann mit usart_transmit() sendet?
Sodass im Hyperterminal auch diese Zahl ankommt?

gruß
beni

von crazy horse (Gast)


Lesenswert?

Was benutzt du denn für einen gestutzten Compiler? Printf() sollte
eigentlich bei JEDEM funktionieren, das ist die zentrale
Ausgabefunktion von C.

von Matthias (Gast)


Lesenswert?

Hi

printf() beim AVRGCC funktioniert aber nur mit einer zusätzlichen
Routine die die einzelnen Zeichen ausgibt. Und diese Funktion muß man
selber bereitstellen.

Lösung:

char buffer[7],i,*s;
unsigned int  ticks=134;
itoa( ticks2, buffer, 10);

s=buffer;

while(*s)
{
    usart_transmit(*s);
    s++;
}

Matthias

von crazy horse (Gast)


Lesenswert?

ach du Elend, was ist denn das fürn Ding?? Dann kauf ich mir doch lieber
was ordentliches als mich mit solchen Sachen rumzuplagen.
Gibts einen bestimmten Grund, warum das beim GCC nicht drin ist?

von Matthias (Gast)


Lesenswert?

Hi

woher soll denn der AVRGCC wissen wohin die Ausgabe von printf soll?
LCD? RS232? USB? Parallel? I2C? SPI? Und eben dafür, um die Ausgabe
eines Zeichens zu realisieren, muß man eine eigene Routine
bereitstellen.

Matthias

von crazy horse (Gast)


Lesenswert?

dafür passt man normalerweise die Funktion putchar() an, wenn man was
anderes als die (für MCs eigentlich Standartschnittstelle UART)
benutzen will. Aber das nützt ja jetzt auch alles nicht :-)

von Josef (Gast)


Lesenswert?

// UART initialization
        // Communication Parameters: 8 Data, 1 Stop, No Parity
        // UART Receiver: Off
        // UART Transmitter: On
        // UART Baud rate: 38400
        UCR=0x08;
        UBRR=0x0C;




 //***********************Zahl in BCD umrechnen und an Anzeige
schreiben*******************************
void Convert_Numb (int Zahl)
        {
        int Help;

            Help  = Zahl / 1000;
            Byte_T  = Help + 0x30;

            Zahl = Zahl - (Help * 1000);
            Help  = Zahl / 100;
            Byte_H  =  Help + 0x30;

            Zahl = Zahl - (Help * 100);
            Help  = Zahl / 10;
            Byte_Z  =  Help + 0x30;

            Zahl = Zahl - (Help * 10);
            Help  = Zahl;
            Byte_E  =  Help + 0x30;

        }
//**********************//4 Zeichen an die
Matrix-LCD**************************************



//Hier ein Macro zum Zeichen ausgeben

#define Put_Char(Data)                      while (( USR &
b00100000) ==  0);  UDR = Data;    //Ein Zeichen an die UART


//Zahl ausgeben


 Put_Char(Byte_E);
 Put_Char(Byte_Z);
 Put_Char(Byte_H);
 Put_Char(Byte_T);


//Alles getestet -läuft gut Byte_x sind als globale Variablen zu
definieren

//nicht allzu elegant, funktioniert aber super und brauch fast keinen
Code

Josef

von Beni Zaiser (Gast)


Lesenswert?

Hallo Matthias,
vieeeeeeelen Dank für diesen genialen Code.
Es funktioniert!!!!!!!!!! Endlich, nach so langem rumprobieren.
Hab absolut keine Probleme mehr.
Juhuuuuu

von Josef (Gast)


Lesenswert?

Meintest du den Code von Josef ?


JOSEF

von Beni Zaiser (Gast)


Lesenswert?

ne den von Matthias.
Hab den ersten genommen, weil er der erste war und der Code so schön
klein.
Hät er nicht funktioniert hätt ich deinen genommen Josef!

von mru (Gast)


Lesenswert?

hallo,

bin grad, jahre nach dem originalen post, über diese diskussion 
gestolpert.

ich möchte keinesfalls gemein sein oder so,
jeder beginnt irgendwo mal.

jedoch frag ich mich wie man auf die idee kommt, µC programmieren zu 
wollen ohne den geringsten dunst von c zu haben.

bitte leute,
kauft euch mal ein gutes buch,
denken drücken sprechen.

hochachtungsvoll.

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.