Forum: Mikrocontroller und Digitale Elektronik Exponentialfunktion auf Atmega8535 sinnvoll?


von Phillip H. (philharmony)


Lesenswert?

Servus,
Ich möchte Werte auf 6-Stellige 7 Segment displays ausgeben.
Bisher habe ich das ganze nur für Dezimal gemacht und anstatt einer 
schleife einfach nach einander 100000, 10000, 1000, 100, und 10 
abgezogen.
Da jetzt aber die noch Möglichkeit bestehen soll, die Basis zu wählen, 
(also hauptsächlich decimal oder hex, evtl oktal), dachte ich an eine 
schleife.
Ich würde also den Int-Wert in die einzelnen Ziffern zerlegen, indem ich 
vom Wert so lange (Basis exp(stelle)) abziehe bis die Zahl kleiner wird, 
dann kommt die nächste Ziffer dran.
Alternativ könnte ich drei if/else-Zweige machen und für die jeweilige 
Basis die Ziffern nach einander "Hard Coded" ermitteln.
Da der Controller noch ne Menge aderes zu tun hat frage ich mich, wie 
lange eine exp() ausführung dauert (denke das wird auch eine schleife 
sein oder?) oder ob ich bei der geringen Anwendungszahl lieber die drei 
Zweige nehme...kann man das so pauschal beantworten?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Das geht auch einfacher, wenn du die Basis kennst kannst du einfach 
fortlaufend Multiplizieren:
1
x = basis
2
for i = 1 to 6
3
 Bestimme Stelle i mit x
4
 x = x * basis
5
end for
Ansosnten hängt das ganze auch davon ab ob der AVR ne HW Multiplizierer 
hat.

von Phillip H. (philharmony)


Lesenswert?

Sorry könntest Du den Codeschnipsel kurz erläutern? Ich steige grad gar 
nicht durch was da passieren soll bzw wo ich da die einzelnen Stellen 
rausbekomme. Ich schreibe übrigens in C.
Habe auch grade im Datenblatt nachgeschaut, der AVR hat diverse 
Multiplikations-Instructions im Arithmetik-Bereich, alle brauchen 2 
Clocks.

Edit: Habe grade gemerkt daß "Exponentialfunktion" der falsche Ausdruck 
ist für das was ich will.
Ich brauche dazu doch eher den math.h befehl pow(). Aber auch der wird 
wohl eine schleife von multiplikationen sein nehmen ich an...

von Phillip H. (philharmony)


Lesenswert?

Habe das jetzt erstmal so gelöst
1
for(i=5;i>=0;i--)
2
{
3
  int power = pow(base, i);//vergleichswert bilden (basis^i)
4
  dig = 0;       //dig zurücksetzen
5
  while(x > power)     //solange x größer ist als vergleichswert
6
  {
7
    x-= power;       //vergleichswert abziehen
8
    dig++;       //digit hochzählen
9
  }
10
  figure[i] = code[dig]     //stelle codiert abspeichern
11
}

In code[] stehen die binärcodes für die 7Seg zeichen von 0-F plus blanc 
und dec-point.
Der Variablen-name "power" passt mir noch nicht, wie nennt man denn 
sowas?
Für i brauche ich jetzt ein signed char, damit nach 0 die -1 kommt die 
dann kleiner ist als 0 und er die scleife abbricht, richtig?

von Karl H. (kbuchegg)


Lesenswert?

Phillip Hommel schrieb:
> Habe das jetzt erstmal so gelöst

pow ist eine ziemlich teure Funktion, die du nicht benutzen solltest, 
wenn du nicht musst.

Schau dir einfach mal die Datentypen dafür an. pow muss auch mit 
Gleitkommazahlen klarkommen.

zb. muss
   pow( 2.0, 0.5 );
die Wurzel berechnen aus 2.0 berechnen.

Das Ganze läuft daher über Logarithmen.

   a hoch b <==>  e hoch ( ln (a) * ln (b) )

von Karl H. (kbuchegg)


Lesenswert?

1
  digitFaktor = 1;
2
  for( i = 0; i < 6; ++i )
3
    digitFaktor *= base;
4
5
  for( i = 5; i >= 0; i-- )
6
  {
7
    dig = 0;       //dig zurücksetzen
8
    while( x > digitfaktor )
9
    {
10
      x -= digitFaktor; // vergleichswert abziehen
11
      dig++;            //digit hochzählen
12
    }
13
    digitFaktor /= base;
14
15
    figure[i] = code[dig]     //stelle codiert abspeichern
16
  }

von Phillip H. (philharmony)


Lesenswert?

Super, Danke mal wieder für die Lösungen. Daß pow so viel Arbeitet hatte 
ich befürchtet, das mit dem digitfaktor macht ja dann das, was ich 
hinter pow erhofft hatte. Merci.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Phillip Hommel schrieb:
> Sorry könntest Du den Codeschnipsel kurz erläutern? Ich steige grad gar
> nicht durch was da passieren soll bzw wo ich da die einzelnen Stellen
Karl heinz war schneller ;)

> Edit: Habe grade gemerkt daß "Exponentialfunktion" der falsche Ausdruck
Hab ich jezt mal stillschweigend eine Textersetzung gedanklich 
durchgeführt ;)

von Phillip H. (philharmony)


Lesenswert?

Mir ist auch noch aufgefallen daß ich die Schleife
1
for( i = 5; i > 0; i-- ) //<-- Hier das >= zu > geändert
2
  {
3
    dig = 0;       //dig zurücksetzen
4
    while( x > digitfaktor )
5
    {
6
      x -= digitFaktor; // vergleichswert abziehen
7
      dig++;            //digit hochzählen
8
    }
9
    digitFaktor /= base;
10
11
    figure[i] = code[dig]     //stelle codiert abspeichern
12
  }

Nur bis Stelle 1 laufen lassen muß. Das was überbleibt sind ja schon die 
"Einer" (basis^0).

von Karl H. (kbuchegg)


Lesenswert?

Läubi .. schrieb:
> Phillip Hommel schrieb:
>> Sorry könntest Du den Codeschnipsel kurz erläutern? Ich steige grad gar
>> nicht durch was da passieren soll bzw wo ich da die einzelnen Stellen
> Karl heinz war schneller ;)

Aber ich glaube ich hab einen Fehler eingebaut

Das muss heißen
  digitFaktor = 1;
  for( i = 0; i < 5; ++i )
    digitFaktor *= base;

Also um 1 weniger als Stellen vorhanden sind.
Denn der unterste Stellenwertfaktor ist ja 1

von Phillip H. (philharmony)


Lesenswert?

Stimmt, der kleinste Wert ist ja Basis^0 und der wird ja vorher schon 
gesetzt.
Konnte es noch nicht testen da ich kein 7seg Hier habe aber werde mir 
morgen die einzelnen ziffern mal ausgeben lassen.
Das Programm schnurrt schon schön vor sich hin...

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.