Forum: Mikrocontroller und Digitale Elektronik PIC18 Algorithmus Implementieren


von Maximilian (Gast)


Lesenswert?

Hallo,
ich habe mir einen kleinen Algorithmus ausgedacht, den ich auf einem 
PIC18F in Assembler implementieren will.
Jedoch habe ich Probleme, wie ich am besten mit Nachkommastellen umgehen 
soll.
Ich habe zum testen schnell ein C# Programm geschrieben um zu prüfen ob 
er auch funktioniert.
1
        static void Main(string[] args)
2
        {
3
            double t0 = 1.0 / 1000;
4
            double tn = t0;
5
            double wi = 100000 / 1.0;
6
7
            for(int i = 0; i < 1000; ++i)
8
            {
9
                Console.WriteLine("Stepper motor make one step.");
10
11
                double timer0Count = tn * 1000000;
12
13
                Console.WriteLine("Timer 0 wait {0} micro seconds.", timer0Count);
14
15
                tn = (1.0 / (1.0 / tn + tn * wi));
16
            }
17
18
            Console.ReadLine();
19
        }
In C# konnte ich ja noch bequem double oder float benutzen, den Luxus 
habe ich ja auf dem PIC nicht.
Eigentlicher Sinn ist es den Timer 0 Wert zu berechnen.
Da mein PIC mit 8MHz arbeitet und der Timer0 einen Prescaler von 1:2 hat 
brauche ich den berechneten Wert also in Mikro Sekunden.

Kann mir jemand helfen, die Rechnung in eine komfortablere Form zu 
bringen, sodass ich auf dem PIC vielleicht ohne Nachkommastellen rechnen 
kann?

von Vincent H. (vinci)


Lesenswert?

Du musst einen ganz speziellen PIC haben, dass der keine Doubles 
"kann"... ;)

von Karsten (Gast)


Lesenswert?

Maximilian schrieb:
> Kann mir jemand helfen, die Rechnung in eine komfortablere Form zu
> bringen, sodass ich auf dem PIC vielleicht ohne Nachkommastellen rechnen
> kann?

Wenn dir das Komma nicht gefällt verschiebe es doch solange nach rechts 
bis es weg ist

von Maximilian (Gast)


Lesenswert?

Wenn ich aber z.B. von Anfang an mit Mikrosekunden rechne entstehen die 
Kommas wieder woanders.
Ich kann nicht einfach Kommas verschieben.
Und ich weiß, dass man die Fließkomma Arithmetik natürlich auch in der 
Software implementieren kann.
Das ist aber ziemlich aufwendig und vor allem langsam.

von udo (Gast)


Lesenswert?

Wieso kannst du keine Kommas verschieben ?
Solange die Gleichung gleich ist, ist das
doch völlig egal.

von Maximilian (Gast)


Lesenswert?

Dann verstehe ich dich nicht ganz.
Zeig mal bitte wie du das meinst.

von Karl M. (Gast)


Lesenswert?

Maximilian,

ein Algorithmus ist doch etwas anderes.

Du müsstest hier die Grundlagen der Mathematik nutzen.
Es sieht nicht so aus, als könntest Du effektiv programmieren..

Was kommt hier wohl raus, wenn man die unnützen Divisionen weglässt ?
1
tn = (1.0 / (1.0 / tn + tn * wi));

von micha (Gast)


Lesenswert?

Und was soll dieser blödsinn
bedeuten ?
Was soll denn da raus kommen wenn man das rechnet ?
Wofür hier rechnen lassen ?

double wi = 100000 / 1.0;

von Maximilian (Gast)


Lesenswert?

Es geht nur um diese Zeile:
tn = (1.0 / (1.0 / tn + tn * wi));
Die möglichst effizient auf Mikrosekunden genau auszurechen.

von Daniel A. (daniel-a)


Lesenswert?

Das ist tatsächlich etwas Komplizierter. Das Problem ist die Addition 
unter dem Bruch, diese verhindern das Entfernen der Kehrwerte. Man 
müsste wohl den Kehrwert von tn speichern. Ausserdem ist dies keine 
lineare Funktion... Schwierig.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Maximilian schrieb:
> Es geht nur um diese Zeile:
> tn = (1.0 / (1.0 / tn + tn * wi));
> Die möglichst effizient auf Mikrosekunden genau auszurechen.

Da wird man schon was basteln koennen, aber das wird in dem Fall nicht 
viel helfen, denn ein Problem bei Integerdivisionen ist die 
Ungenauigkeit durch den Divisionsrest.
Weil tn immer wieder durch diese Formel gejagt wird, werden sich die 
Ungenauigkeiten schnell aufsummieren; in dieser rekursiven Form:

tn_neu=f(tn_alt)

sollte man das nicht machen. Was besser funktioniert, aber ich weiss 
nicht, ob's hier weiterhilft, waere, wenn

tn=f(i)

auch ginge.
Dann wird jedes tn nur mit den Rundungsfehlern aus einer Berechnung 
behaftet sein und nicht mit den Fehlern aus allen vorhergehenden.


Ich vermute mal, dass in dem Fall die Funktion tn=f(i) ungefaehr von 
diesem Kaliber ist:

tn=A/(B+sqrt(i))

A und B muss man halt mal ausrechnen und dann koennt' ich mir 
vorstellen, das mit einer Potenzreihe anzunaehren (Die Wurzel ist nicht 
wirklich schoener als eine Integerdivision). Wenn das klappt, braucht's 
nur noch Divisionen durch Konstante.

Gruss
WK

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.