Forum: Mikrocontroller und Digitale Elektronik atmega8 Dez to: Hex & Bin [ funktioniert nur zum Teil!]


von Jan (Gast)


Lesenswert?

Hallo,
habe grade den code fertig geschrieben,
um eingegebene Dezimal Zahlen in hex und binär Zahlen auszugeben,
das mit dem Hex klappt ohne probleme,
die Binär Zahl gibt er mir allerdings falsch auf dem Display (HD44780)
aus.
Ich erhalte zahlen wie -12739.

Auf dem Pc klappt alles ohne Probleme.
Der pc code ist der 2.
Hoffe ihr wisst wo der Fehler liegt :)
MfG

 hier der code vom atmega8:

#include <avr/io.h>
#include "lcd-routines.h"
#include <stdio.h>


int main(void)
{
char text[16];
int rest = 0, max = 8, i = 0, w = 0, q = 1, leer = 0, eingabe = 32;


lcd_init();
lcd_setcursor(0, 1);
lcd_string("hex: ");
lcd_setcursor(8, 1);
sprintf(text,"%X",eingabe);
lcd_string(text);
while(w < max)
{
rest = eingabe%2;
eingabe = eingabe/2;
w++;
   if(rest>=1)
   {i = i + q;}
   else
   {i = i + leer;}
q = q*10;
}
lcd_setcursor( 0, 2);
lcd_string("binär: ");
lcd_setcursor( 8, 2);
sprintf(text,"%d",i);
lcd_string(text);
return 0;
}


hier der pc code:

// deztobin.cpp : Definiert den Einstiegspunkt für die 
Konsolenanwendung.
//

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
int rest = 0, bin = 0, max = 8, i = 0, w = 0, q = 1, leer = 0, eingabe = 
0;


cout << "\n\geben sie eine zahl kleiner als 256 ein: ";
cin >> eingabe;
cout << endl << "dezimal: \t"<< eingabe;
cout << endl << "hexadezimal: \t";
printf("%X",eingabe);
cout << endl;
while(w < max)
{
rest = eingabe%2;
eingabe = eingabe/2;
w++;
   if(rest>=1)
   {i = i + q;}
   else
   {i = i + leer;}
q = q*10;
}
cout << "Binaer: \t" << i;
cin.get();
cin.get();
main();
return 0;
}

von Stefan E. (sternst)


Lesenswert?

Jan schrieb:
> Ich erhalte zahlen wie -12739.

Weil 100000 nun mal nicht in einen 16 Bit int rein passt.

Jan schrieb:
> Auf dem Pc klappt alles ohne Probleme.

Weil dort ein int größer ist.

von Jan (Gast)


Lesenswert?

wie groß soll das den sein?
so richtig habe ich es noch ncith kappiert :/
dachte immer 10000000, passen darein weil 11111111 sind doch 1 byte also 
8 bit,
kannst du es mir evtl kurz erklären :/

von Karl H. (kbuchegg)


Lesenswert?

Jan schrieb:
> wie groß soll das den sein?
> so richtig habe ich es noch ncith kappiert :/

ein 16 Bit int hat einen Wertebereich von -65536 bis +65535

> dachte immer 10000000, passen darein weil 11111111 sind doch 1 byte also
> 8 bit,

Die Bitzahlen sind uninteressant.
Was du berechnest ist ja eine Dezimalzahl. Du berechnest den Wert 10 und 
vertraust darauf, dass derjenige, der vor dem Bildschirm sitzt, das 
nicht als "Zehn" sondern als "1-Bit 0-Bit" liest.
Berechnet hast du es aber als Zehn

(Die ganze Vorgehensweise ist nicht besonders gut geeignet. In 
Wirklichkeit willst du nämlich eigentlich einen String mit 8 Zeichen 
bestimmen, bei dem jedes Zeichen entweder '0' oder '1' sein kann und die 
Anordnung der '0' und '1' mit dem Bitmuster einer Zahl übereinstimmt. 
Strings können beliebig lang sein)

von Stefan E. (sternst)


Lesenswert?

Jan schrieb:
> dachte immer 10000000, passen darein weil 11111111 sind doch 1 byte also
> 8 bit,

Du wandelst es aber um in eine wie eine Binärzahl aussehende 
Dezimalzahl. Du wandelst z.B. eine Drei um in eine Elf, damit die 
dezimale Ausgabe so aussieht, wie die binäre Darstellung der Drei. Und 
so wird aus der 32 bei dir Einhunderttausend, und Einhunderttausend 
passt in ein 16 Bit int nicht rein.

Edit: Mein Gott bin ich heute langsam beim Tippen. ;-)

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> ein 16 Bit int hat einen Wertebereich von -65536 bis +65535

Ähm ... hüstel ... das wäre dann wohl eher ein 17 Bit int ;-)

von Jan (Gast)


Lesenswert?

also habe jetzt n programm geschrieben, das mir sagt das ich 25bit 
brauche,
ich werde es mal eben testen :)

von Jan (Gast)


Lesenswert?

mhh :/
habe jetzt 25 bit eingegeben,
und das i zum float dem entsprechend unten das %d zu %f,
jetzt zeigt er mir ein "?" an.
:/

von Karl H. (kbuchegg)


Lesenswert?

Jan schrieb:
> also habe jetzt n programm geschrieben, das mir sagt das ich 25bit
> brauche,
> ich werde es mal eben testen :)


?
Du kommst immer weiter vom Kurs ab.

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:
> Karl Heinz Buchegger schrieb:
>> ein 16 Bit int hat einen Wertebereich von -65536 bis +65535
>
> Ähm ... hüstel ... das wäre dann wohl eher ein 17 Bit int ;-)

zu recht gehüstelt.

Fürs Protokoll: 16 Bit int gehen von -32768 bis +32767
ISt für seine Aufgabenstellung allerdings uninteressant. Er muss sich 
endlich davon lösen, dass diese Konvertierung eine Zahlenkonvertierung 
ist.

Binär bzw. Hex sind nur verschiedene Darstellungen derselben Zahl. Und 
diese Darstellung geschieht in Form eines Strings. Das sich dieser 
String bei binärer Darstellung nur aus den Zeichen '0' und '1' 
zusammensetzt ist zwar schön, sagt aber nichts darüber aus, dass man das 
als Zahl ansehen kann.

Jan: wie willst du denn mit deinem Schema Hexadezimalzahlen darstellen? 
Die kriegst du nämlich nicht dadurch hin, dass du dir eine Dezimalzahl 
zusammenbastelst, die so aussieht als ob es eine Hexzahl sein könnte.

von Jan (Gast)


Lesenswert?

@Karl habe ich mir schon gedacht komme aber nicht auf den richtigen 
gedanken :(

und 2.

Du meinst wohl Binär statt Hex, oder?
naja am pc funktioniert es ja wunderbar,
compilier es selbst zwar fehlern links imemr die restlichen nullen 
(falls vorhanden) aber das macht ja nichts da das Byte ja immer 8 bits 
hat.
den rest denke ich mir hinzu.


Und naja am pc funktioniert es reibungslos, nur am Mikrocontroler eben 
nicht,
er gibt mir immer falsche zahlen aus auch wnen ich den Wert von 16bit 
auf 25 bit änder,
weiß einfach nicht mehr was ich machen soll.
bei der eingabe von 189 gibt er mir
Hex: BD
Bin: 18557

ich weiß wirklich nciht weiter :(

von Karl H. (kbuchegg)


Lesenswert?

Jan schrieb:

> Und naja am pc funktioniert es reibungslos, nur am Mikrocontroler eben
> nicht,

Eine Analogie

Du behauptest die Fläche eines Rechtecks berechnet sich als Länge PLUS 
Breite.

Jetzt sagen wir dir: das ist falsch!

Darauf du: Wieso denn? Die Länge sei 2, die Breite sei 2, dann kommt da 
4 raus und das ist ja wohl die Fläche eines derartigen Rechtecks. Ich 
weiß wirklich nicht weiter, warum das bei 3 und 4 nicht auch die 
richtigen Werte ergibt.

Du bist auf dem falschen Dampfer!
Dass du ein PC Programm schreiben kannst, welches auf einem PC mit 32 
Bit Integern dir ein scheinbar richtiges Ergebnis liefert, sagt nichts 
darüber aus, dass die grundsätzliche Idee nicht schon falsch ist. Sie 
ist falsch!

Die Idee, sich eine Dezimalzahl zusammenzubauen, die so aussieht als ob 
sie eine Binärzahl wäre (3 (also: Drei) in 11 (also: Elf) umwandeln) ist 
der falsche Ansatz. Das ist nicht zu retten, egal wie du es drehst und 
wendest.


  char Result[9];

  for( i = 0; i < 8; ++i ) {
    if( Zahl % 2 == 0 )
      Result[ 7 - i ] = '0';
    else
      Result[ 7 - i ] = '1';
    Zahl = Zahl / 2;
  }
  Zahl[8] = '0';

  printf( "%s", Zahl );

von Jan (Gast)


Lesenswert?

ja okay :),
Vielen dank:)
ich bin halt noch anfänger und beschäftige mich jetzt richtig seit einer 
woche mit c++, ich war halt erst mal froh das alles so geklappt hat :)
dein code sieht ziemlich gut aus :)
werde mir wohl in Zukunft mehr gedanken machen bei so etwas wie diesem 
:)
Vielen dank werde den code mal auf dem controler testen, und dannach Ihn 
selber nochmal selbst von anfang an zu schreiben.
aber erst heute abend weil ich gleich weg muss.
Werde mich nochmal melden und nochmal großen dank für die Hilfe :)

von Jan (Gast)


Lesenswert?

So leider läuft der code nicht,
// deztobinforum.cpp : Definiert den Einstiegspunkt für die 
Konsolenanwendung.
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
int i, Zahl;
char Result[9];

  for( i = 0; i < 8; ++i )
  {
    if( Zahl % 2 == 0 )
      Result[ 7 - i ] = '0';
    else
      Result[ 7 - i ] = '1';
    Zahl = Zahl / 2;
  }
  Zahl[8] = '0';

  printf( "%s", Zahl );
  cin.get();
  return 0;
}

der hat wohl Probleme in der Zeile " Zahl[8] = '0';

von Karl H. (kbuchegg)


Lesenswert?

Jo.
Mein Fehler

   Zahl[8] = '\0';

von Jan (Gast)


Lesenswert?

kannst es mir den code kurz erklären möchte es gerne verstehenn :)

von Jan (Gast)


Lesenswert?

klappt imemr noch nciht hier die meldung vom compiler:
(22): error C2109: Index erfordert ein Array oder einen Zeigertyp

von spess53 (Gast)


Lesenswert?

Hi

>klappt imemr noch nciht hier die meldung vom compiler:
>(22): error C2109: Index erfordert ein Array oder einen Zeigertyp

  Zahl[8] = '\0'; -> Result[8] = '\0';

MfG Spess

von Jan (Gast)


Lesenswert?

okay nun compiliert der einwandfrei bekomme dann aber beim debuggen das 
heir raus:
Unbehandelte Ausnahme bei 0x5a2914cf (msvcr100d.dll) in 
deztobinforum.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 
0xffcccccd.

// deztobinforum.cpp : Definiert den Einstiegspunkt für die 
Konsolenanwendung.
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
int i, Zahl = 240;
char Result[9];

  for( i = 0; i < 8; ++i )
  {
    if( Zahl % 2 == 0 )
      Result[ 7 - i ] = '0';
    else
      Result[ 7 - i ] = '1';
    Zahl = Zahl / 2;
  }
  Result[8] = '\0';

  printf( "%s", Zahl );
  cin.get();
  return 0;
}

von Karl H. (kbuchegg)


Lesenswert?

Jan schrieb:
> okay nun compiliert der einwandfrei bekomme dann aber beim debuggen das
> heir raus:

Jan.

Das hab zwar ich verbockt, schon richtig.
Aber du bist der Prototyp eines Forenfragers:
Sobald er merkt, dass ihm jemand seine Arbeit abnimmt, stellt er das 
eigenständige Mitdenken ein, kopiert den Code in sein Projekt und 
überlässt alles weitere demjenigen, der ihm das Codestück gegeben hat.
Und genau das ist auch der Grund, warum ich mehr und mehr davon abkomme, 
schlüsselfertige Lösungen zu liefern. Bzw. nur mehr dann, wenn ich sehe, 
das der Fragesteller anfängt mitzuarbeiten und nicht nur Codestücke 
übernehmen will. Zumindest bis zu einem gewissen Level in der 
Schwierigkeit.


Wie viele andere, schreibe ich Codestücke hier direkt im Edit-Fenster 
und teste sie nicht. Und na klar. Ab und zu passiert es, dass man 
dämliche Fehler macht


>   printf( "%s", Zahl );

Ist natürlich Blödsinn. Das Ergebnis steht im Array Result, welches dann 
auch tatsächlich ein String ist. Zahl war die Ausgangszahl

    printf( "%s", Result );


Solche Dinge musst du schon auch selber sehen können.

von Jan (Gast)


Lesenswert?

Es tut mir ja leid das ich dich so viel frage es liegt einfach nur daran 
das ich deinen code nciht verstehe glaube mir habe selber immer versucht 
irgendwas umzustellen damit dein code läuft mir fehlt aber dafür einfach 
das wißen, ich wollte nicht das du mir die ganze arbeit abnimnmst.
deswgeen ahbe ich dich auch gefragt ob du mir den code erklären könntest 
damit ich die vorgehensweise des codes nachvollziehen kann und selbst 
nachbauen kann :)

von Jan (Gast)


Lesenswert?

So habe den code nun umgewandelt und für meinen controller angepasst :)
hier ist der code :)

Vielen dank nochmal Karl werde mich aber noch intensiv mit dem code 
beschäftigen damit ich ihn ganz verstehe :)

//
// Anpassungen im makefile:
//    ATMega8 => MCU=atmega8 im makefile einstellen
//    lcd-routines.c in SRC = ... Zeileanhängen
//
#include <avr/io.h>
#include "lcd-routines.h"
#include <stdio.h>
#include <util/delay.h>

int main(void)
{
int i, Zahl = 189;
char Result[9], text[16], texxt[16];
//cout << endl << "Dezimal Zahl: ";
//Cin >> Zahl;
lcd_init();
lcd_setcursor(0, 1);
lcd_string("Hex: ");
lcd_setcursor(8, 1);
sprintf(text,"%X",Zahl);
lcd_string(text);

  for( i = 0; i < 8; ++i )
  {
    if( Zahl % 2 == 0 )
      Result[ 7 - i ] = '0';
    else
      Result[ 7 - i ] = '1';
    Zahl = Zahl / 2;
  }
 Result[8] = '\0';
lcd_setcursor( 0, 2);
lcd_string("Bin: ");
lcd_setcursor( 8, 2);
sprintf(texxt,"%s",Result);
lcd_string(texxt);
return 0;
  return 0;
}

von zagge (Gast)


Lesenswert?

wobei das ganze natürlich ( Division, Modulo etc.) nicht sonderlich 
effizient ist.
Aber vielleicht schnallt es ja der Optimizer.
Am besten aber gleich >> und & verwenden

von Jan (Gast)


Lesenswert?

naja jetzt muss ich erst mal den code selber komplett kappieren :)
dannach werde ich einen keypad mit 4*4 knöpfen dran bauen so das ich die 
Zahl selber eingeben kann.
Aber das braucht noch zeit :)

von Karl H. (kbuchegg)


Lesenswert?

zagge schrieb:
> wobei das ganze natürlich ( Division, Modulo etc.) nicht sonderlich
> effizient ist.

Ist ziemlich wurscht, solange er mit

  int i, Zahl;

  for( i = 0; i < 8; ++i )

für den µC ein Beschäftigungstherapieprogramm zusammengestellt hat.


> Aber vielleicht schnallt es ja der Optimizer.
> Am besten aber gleich >> und & verwenden

Schlechter Rat.
Nimm das, was in der Situation am logischten ist. Wenn du dann noch die 
richtigen Datentypen nimmst UND man das optimieren kann, dann optimiert 
das schon der Compiler. Die machen sowas seit 30 Jahren routinemässig.

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.