mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C Problem mit Umwandlung


Autor: Beni Zaiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Beni Zaiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Beni Zaiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Fiffi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"

Autor: Fiffi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Beni Zaiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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??

Autor: Beni Zaiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Josef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Würde einmal Ascii Zeichen schicken !

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

Josef

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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++)
}

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Beni Zaiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

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

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Josef (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Beni Zaiser (Gast)
Datum:

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

Autor: Josef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meintest du den Code von Josef ?


JOSEF

Autor: Beni Zaiser (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: mru (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.