Forum: Mikrocontroller und Digitale Elektronik C Problem


von schurli (Gast)


Lesenswert?

Hi

Ich habe ein kleines Problem mit meinem 8051 und meinem C-Programm.

Ich habe eine Ausgabefunktion für einen 7-Segment Treiber die so 
definiert ist:

void MAX7219_Write (unsigned char reg_number, unsigned char dataout)
{.....
}


Ich will aus einer beliebigen Stelle in meinem Programm auf diese 
Funktion zugreifen.

Das Problem: Anscheinend kommt der µC nicht mit der Variable "h1" 
zurecht.

float a1;
int h1;

######################################################
t1[1]=9312;

      a1=t1[1]/1000;               //a1=9312/1000=9,312
      h1=(int)a1;
      MAX7219_Write (xx,h1);
######################################################

Wenn ich statt h1 eine Zahl schreibe: z.B.: MAX7219_Write (xx,5)
dann funktioniert die Funktion????

Ps: Keil µVision kommt bei der Simulation damit zurecht

mfg Schurli

von Rahul D. (rahul)


Lesenswert?

>void MAX7219_Write (unsigned char reg_number, unsigned char dataout)
>h1=(int)a1;

Deine Typen passen nicht wirklich gut zueinander...

von schurli (Gast)


Lesenswert?

es funktioniert auch so nicht:

h1=(int)a1;   //Die Kommastellen werden "abgeschnitten"
h2=(char)h1;
MAX7219_Write (xx,h2);

von Magnus Müller (Gast)


Lesenswert?

schurli wrote:
> es funktioniert auch so nicht:
>
> h1=(int)a1;   //Die Kommastellen werden "abgeschnitten"
> h2=(char)h1;
> MAX7219_Write (xx,h2);

Du musst "h2" auf jeden Fall auch als unsigned char anlegen. Es reicht 
nicht aus, einer int-Variable einen zu char gecasteten Wert zuzuweisen.

Gruß,
Magnetus

von schurli (Gast)


Lesenswert?

ohne Ergebnis

Unter Keil läuft es, aber am 8051er nicht :-(

von Magnus Müller (Gast)


Lesenswert?

Was solls... Bilder (oder in diesem Fall Code) sagen mehr als tausend 
Worte...

float a1;
unsigned char h1;                  // <-- hier ändern...

######################################################
t1[1]=9312;

      a1=t1[1]/1000;               //a1=9312/1000=9,312
      h1=(unsigned char)a1;        // <-- ...und hier ändern.
      MAX7219_Write (xx,h1);
######################################################

Gruß,
Magnetus

von Magnus Müller (Gast)


Lesenswert?

> Das Problem: Anscheinend kommt der µC nicht mit der Variable "h1"
> zurecht.

> Unter Keil läuft es, aber am 8051er nicht :-(

...und WAS funktioniert da nicht? Wie äussert sich denn der Fehler???

von schurli (Gast)


Lesenswert?

unsigned char f=4;

  MAX7219_Write (xx,f);

wird angenommen, also klappt die "int to char" anweisung nicht

von Rahul D. (rahul)


Lesenswert?

Mach den Cast richtig, und es sollte gehen.
Wenn nicht, dann liegt es an einen anderen Teil in deinem Programm (char 
!= unsigned char)

von Magnus Müller (Gast)


Lesenswert?

schurli wrote:
> unsigned char f=4;
>
>   MAX7219_Write (xx,f);
>
> wird angenommen, also klappt die "int to char" anweisung nicht

"wird angenommen"... Es klingt so, als ob du uns damit sagen willst, 
dass dein COMPILER beim compilieren meckert bzw. nicht meckert, oder?

Wenn dein Compiler meckert, dann lass uns doch bitte mal wissen WAS er 
da böses von sich gibt!

Gruß,
Magnetus

von schurli (Gast)


Lesenswert?

der Fehler liegt hier begraben:

int a=7;
unsigned char f;
f=(unsigned char)a;
MAX7219_Write (xx,f);
---FUNKTIONIERT!, die 7 wird ausgegeben

Ich will in meinem Programm aber folgendes:
eine Zahl die in einem Feld gespeichert ist z.b.: 3278 in einzelne 
Ziffern aufspalten und ausgeben.

Meine Anweisung, dass ich an die 1000-er Stelle rankomme ist folgende:

int t[10];
t[2]=3278;
float a;
int h;
unsigned char f;

a=t[2]/1000;               //a=3278/1000=3,278
h=(int)a;                   //die Kommastellen werden abgeschnitten
f=(unsigned char)h;
MAX7219_Write (xx,f);

Leider funktioniert die Division nicht?!

von schurli (Gast)


Lesenswert?

Der Compiler meckert nicht! Leider funktioniert das Programm im 
Compiler, aber nicht am µC.

von Karl H. (kbuchegg)


Lesenswert?

> Leider funktioniert die Division nicht?!

Was bedeutet das?
Lass dir doch nicht alles aus der Nase ziehen!
Wir sind doch keine Hellseher.

Dir ist schon bewusst, dass t[2]/1000 ein ganzzahliges
Ergebnis liefert, da sowohl t[2] als auch 1000 ein int ist.
Das Ergebnis ist daher nicht 3.278 sondern schlicht und
ergreifend 3. Bei der Zuweisung an a wird dann das Ergebnis
auf double erweitert, a erhält also den Wert 3.0
Theoretisch. Es könnte auch 2.99999999 sein, was dann bei
der nachfolgenden
      h = (int)a;
zu einem Wert von 2 in h führt.

Da du dann allerdings sowieso wieder den Ganzzahl Anteil
von a nimmst, sollte das Ergebnis also 3 sein.

Daher: Bitte mach endlich mal konkrete Aussagen und hülle
dich nicht in interessant klingende, aber nichtssagende
Aussagen wie: das funktioniert nicht.

von Karl H. (kbuchegg)


Lesenswert?

> Leider funktioniert das Programm im Compiler

Und bitte hör mit diesem Unfug auf. Dein Pgm kann nicht
in deinem Compiler 'funktionieren', weil es dort gar
nicht ausgeführt wird. Es interssiert deinen
Compiler nicht die Bohne, was dein Programm macht. Alles
was deinen Compiler interessiert ist, ob dein Machwerk
den Grammatikregeln der Sprache C genügt. Die Logik
in deinem Programm ist ihm sch...egal.

Wenn du also meinst, dass dein Compiler den Quelltext ohne
Kommentar akzeptiert, dann sag ganz einfach: es compiliert
ohne Warnungen oder Fehler. Allerdings gehen wir normalerweise
sowieso davon aus, dass es weder Warnungen noch Fehler gibt,
es sein denn, der Fragesteller erwähnt diese. Dann allerdings
ist es hilfreich, wenn er den genauen Fehlertext angibt und sich
nicht in mystischen Andeutungen wie: 'mein Compiler mag mich nicht'
ergeht.

von Johann K. (hansi)


Lesenswert?

Wenn du nur die vier oder fünf Stellen der Zahl selektieren willst
forderst du  deinem 8051 aber ganz schön Rechneleistung und
Speicherplatz durch die Verwendung von Fließkommazahlen.

Diese Aufgabe hatte ich auch schon ein paar mal zu lösen.
Hier mein Weg:

- über Modulo die höchste Ziffer ermitteln;
- Ziffer anzeigen;
- Ziffer*Stelle von der Zahl subtrahieren;
- und jetzt das selbe Spiel mit der nächstkleineren Zehnerstelle;
- bis Ende und fertig.

Also:
int t[10];
t[2]=3278;

int c, ziffer;  // wichtig! mindestens so lang wie Datenquelle

c = t[2];
ziffer = c%1000;
MAX7219_Write (xx,(unsigned char)ziffer);  // die Tausenderstelle
c -= ziffer*1000;
ziffer = c%100;
MAX7219_Write (xx,(unsigned char)ziffer);  // die Hunderterstelle
c -= ziffer*100;
ziffer = c%10;
MAX7219_Write (xx,(unsigned char)ziffer);  // die Zehnerstelle
c -= ziffer*10;
MAX7219_Write (xx,(unsigned char)ziffer);  // die Einerstelle

von Johann K. (hansi)


Lesenswert?

Fehler, Fehlerchen, Fehlerteufel!

Ich hätte besser gleich in meinen alten Quellen nachgesehen
oder besser mitgedacht.

Es ist natürlich nicht Modulo (%)
sondern die ganz normale Division (/) !!!

Modulo musst du verwenden, wenn du von der Einerstelle aus anfangen 
willst!

von Peter D. (peda)


Lesenswert?

Vielleicht solltest Du erstmal in der Doku zu Deiner 
MAX7219_Write-Funktion nachschauen.

Ich vermute mal, die gibt einfach nur die beiden Bytes aus.

In dem Fall mußt Du noch im Datenblatt des MAX7219 nachschauen, was die 
beiden Bytes für ne Bedeutung haben.


So einfach ohne Sinn und Verstand Funktionen aneinander zu pappen und 
hoffen, daß es funktioniert ist nicht, sind ja schließlich keine 
Legosteinchen.


Peter

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.