PIC18 Algorithmus Implementieren

Gast #4466384
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?
Gast #4466414
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.
Gast #4466436
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));
#4466576
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren