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.
:
Wiederhergestellt durch User
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.