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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.