Forum: Mikrocontroller und Digitale Elektronik Timerregister berechnen


von Frank (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

: Wiederhergestellt durch User
von Karl H. (kbuchegg)


Lesenswert?

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.

von Frank (Gast)


Lesenswert?

Hallo Karl Heinz,

vielen Dank für die Antwort.
Das muss ich erst einmal verdauen.

Gruß Frank

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.