Timerregister berechnen

Gast #2947992
Hallo,

folgende knifflige Aufgabe.
Vielleicht können mir Mathematiker dabei helfen.

Ich habe einen Timer mit folgenden 3 Registern, die es zu befüllen gibt 
um eine vorgegebene Zeit zu realisieren:

1. Clockdivider mit möglichen Teilern 0, 2, 4
2. Prescaler = 16Bit
3. Timer = 16Bit

Das bedeutet, dass ich Zeiten von 1 Takt bis max. 65535*65535*4 Takte 
damit realisieren kann.

Wie bekomme ich eine Berechnung der Registerwerte aus einer Zeitangabe 
in zB.µs hin?

Der Timertakt ist durch zurücklesen und auswerten von verschiedenen 
Register bekannt. D.h. somit ist die Periodendauer in der Funktion 
bereits als kleinste Zeiteinheit berechnet.
Die Berechnung der Tackanzahl ist auch schon vorhanden.

Bsp: BenötigteTackte = (TimeMicroSecond * 1e-6) / (1/SystemClock);

Jetzt geht es darum:
Wie muss ich die "BenötigteTackte" mit Hilfe von Algorithmen in die 
Register verteilen, damit dann die richtige Zeit eingestellt ist?

Ich habe mich hoffentlich verständlich ausgedrückt und hoffe auf Eure 
Hilfe.

Vielen Dank Frank
Frank schrieb:

> Jetzt geht es darum:
> Wie muss ich die "BenötigteTackte" mit Hilfe von Algorithmen in die
> Register verteilen, damit dann die richtige Zeit eingestellt ist?

Wenn wir mal den Clockprescaler aussen vor lassen, dann ist die weitere 
Aufgabenstellung äquivalent mit:

Suche 2 Zahlen X und Y, so dass das Produkt aus X und Y eine Vorgabe Z 
erfüllt.

  Prescaler * Timer = BenötigteTakte;

Wenn einem in der Informatik gar nichts anderes einfällt, dann macht man 
'Brute Force' - brutale Gewalt.
Einfach durchprobieren.

Lass den Prescaler von 1 bis zu sqrt(BenötigteTakte) laufen, rechne dir 
ganzzahlig aus

   Timer = BenötigteTakte / Prescaler;

und stell über die Umkehrung

   ErzielteTakte = Prescaler * Timer;

die Differenz ErzielteTakte zu BenötigteTakte fest, und den mit der 
kleinsten absoluten Differenz nimmst du. Dein Suchraum ist überschaubar 
- so dass du dir ein bischen µC-Schwitzen leisten kannst. Und wenn du 
auf ein Pärchen mit 0 Abweichung stösst, kannst du ja vorzeitig 
abbrechen.

Standardmässig nimmst du einen ClockDivider von 2. Wenn BenötigteTakte 
größer als 65536*65536*2 ist, dann schaltest du um auf einen Divider von 
4 und halbierst dafür die Anzahl benötigter Takte, ehe du dann wieder 
auf die Suche gehst.
Die Motivation hinter diesem Vorgehen ist einfach: Genauer wirds nicht, 
wenn du mit einem höheren ClockDivider dir die Granulierung halbierst. 
Also willst du so lange es geht den kleinsten ClockDivider benutzen.
Frank schrieb:

> Jetzt geht es darum:
> Wie muss ich die "BenötigteTackte" mit Hilfe von Algorithmen in die
> Register verteilen, damit dann die richtige Zeit eingestellt ist?

Wenn wir mal den Clockprescaler aussen vor lassen, dann ist die weitere
Aufgabenstellung äquivalent mit:

Suche 2 Zahlen X und Y, so dass das Produkt aus X und Y eine Vorgabe Z
erfüllt.

  Prescaler * Timer = BenötigteTakte;



Was du suchst ist die Primfaktorzerlegung.
Dabei geht es darum eine Zahl in diejenigen Zahlen zu zerlegen, die
* alle Primzahlen sind
* deren Produkt die gesuchte Zahl ergibt.

Bsp: 4725
Die Primfaktoren sind: 3, 3, 3, 5, 5, 7
Weil 3*3*3*5*5*7 wieder die 4725 ergibt.

Du kannst nun diese Primfaktoren beliebig zusammenfassen, zb
    (3*3) -> 9
    (3*5*5*7) -> 525

und das Produkt aus 9 und 525 ergibt wieder die 4725.

Du könntest aber auch zusammenfasse
      3*3*3*5  -> 135
      5*7      ->  35
und 135*35 ergibt wieder die 4725

Primfaktorzerlegung ist schwieriges Problem. Letzten Endes läuft es 
meistens auf 'wir probieren' raus. (Womit wir wieder beim ersten Posting 
wären)


Und natürlich kann man die beiden Ideen auch kombinieren.
Erst mal trivial feststellen ob in der Zahl eine der potentiellen 
Primfaktoren 2, 3, 5, 7, 11 ein oder mehrmals enthalten ist. Wenn ja 
kannst du sofort die benötigten Takte da mal durchdividieren und so den 
Suchraum für brute Force reduzieren.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.