PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Sinnvoll Vorteilen und das berechnen



RCO
26.08.2005, 14:25
Hallo Leute,

mein Titel ist vielleicht etwas verwirrend, drum wrde ich nun mal erläutern worum es geht. Ich möchte mit einem ATmega8 eine varialbe Frequenz von 1 bis ca. 120-150 Hz. Ausgeben bzw. dann einen Interrupt auslösen. Dazu stehen mir leider nur noch die Timer 0 und 2, als 8-Bit-Timer zur Verfügung, bei denen sich nciht die Obergrenze frei wählen lässt. Ich verwende jetzt einen Vorteiler von 1024. Mit den 8-Bit erreiche ich also eine minimalfrequenz von (16M/1024/256) ca. 61 Hz. Das ist deutlich zu hoch, deshalb werde ich auch noch einen Zähler in der IRQ verwenden müssen ("IRQ-Presc."), der ebenfalls quasi als weiterer Prescaler fungiert.
Für schnellere Frequenzen oberhalb der 61 Hz werde ich den Timer in der IRQ mit einem Wert füllen ("Timervorage").
Nun ist es relativ einfach die 2 Werte vür z.B. 100Hz zu bestimmen:

IRQ-Presc. = 0
Timervorabge = 256-156,25 also ca. 100.

Alzu genau muss das ganze eh nicht sein. Es stellt sich aber das Problem, dass nicht ich die Werte bestimme, sondern der AVR sie ausrechnen soll!

Und das möglichst intelligent. Damit möglichst wenig der kostabren Prozessorzeit verloren geht sollte die IRQ so wenig wie möglich aufgerufen werden, also der IRQ-Presc. und die Timervorgabe möglichst klein sein.
Wie lassen sich diese beiden Werte also sinnvoll bestimmen, wenn ich nur eine Anzahl der Ereignisse pro Sekunde vorgebe?

Mir ist schon relativ klar, dass ich zwischen 2 Fällen Unterscheiden sollte, Vorgabe über oder unter 61!
Je nachdem welcher Fall es ist, wird entweder an der Timervorgabe oder dem IRQ-Presc. "gedreht". Allerdings kommen da gerade in dem Bereich um 60 sehr ungenau Werte raus. Für eine Vorabge von 60 wäre z.B. diese Lösung optimal:

IRQ-Presc. = 2
Timervorgabe = 256-130 = 126
16M/1024/130/2 = 60,096

Und damit deutlich genauer als:

(Da unter 60 wird die Timervorgabe 0 und nur mit dem IRQ-Presc gearbeitet)

16M/1024/256/1 = 61

Für 45 ist der Fehler sogar noch gravierender!

Also wie ließe sich das günstig ausrechnen, ohne alle Zahlen durchprobieren zu müssen? Ideen?

Oder anders gefragt:


https://www.roboternetz.de/phpBB2/album_pic.php?pic_id=664

Wie kriege ich es hin, dass die Variablen Timervorgabe und IRQ-Presc. möglichst klein sind und für X eine "möglichst natürliche" Zahl rauskommt.

RCO
26.08.2005, 17:35
OK, dann eine kurze Zwischenfrage.
Wie genau rundet der AVR wenn man mit Integern rechnet? Kann man davon ausgehen, dass er die erste Nachkommastelle ab ,5 auf und darunter abrundet?

linux_80
26.08.2005, 17:46
Hallo,
da der AVR von Haus aus garnix mit Kommazahlen am Hut hat, denke ich, das diese einfach abgeschnitten werden !
Runden ist ja schon was kompliziertes.

toeoe
26.08.2005, 17:46
Hi,

genau sagen kann ich dir das leider auch nicht. Aber es gibt doch dafür die Regeln, dass man ab 5 aufrundent, und dadrunter dann abrundet. Sollte sich denk ich jeder dran halten, oder?

Gruß
Thomas

RCO
26.08.2005, 17:52
Hm, es ist schon relativ wichtig, ob er noch rundet, oder generell abrundet.

PicNick
26.08.2005, 19:03
Wenn du mit Integer-Zahlen rechnest, wird abgezwickt. Runden müßtest du selber.

SprinterSB
26.08.2005, 19:42
Wenn du nur zB die Frequenzen von 1..150Hz hast, also 151 Werte oder so, dann kannst du die Prescale-Werte doch einfach ins Flash legen oder ins EEPROM, falls im Flash nicht mehr so viel Platz ist. Das Rechnen überlässt du dann deinem Host zur Compile-Zeit :-)

RCO
27.08.2005, 15:13
Wenn du nur zB die Frequenzen von 1..150Hz hast, also 151 Werte oder so, dann kannst du die Prescale-Werte doch einfach ins Flash legen oder ins EEPROM, falls im Flash nicht mehr so viel Platz ist.

Hm, ist natürlich auch ne Idee, allerdings sind es ja immer 2 Werte, also insgesamt über 300 Werte.


Wenn du mit Integer-Zahlen rechnest, wird abgezwickt. Runden müßtest du selber.

Selber Runden wollte ich nciht und mit Integern soll es ja möglichst schnell gehen. Ich hab noch mal ein wenig drüber nachgedacht. Und das ist dabei rausgekommen:

Variablen:
IRQ-Presc. = Vorzähler in der IRQ
Timervorgabe = Timer-Füllwert in der IRQ
Takte = Takte bis zur nächsten Ausführung
HzVorgabe = Vorgabe wert in Ausführunden pro Sekunde

Takte = 16.000.000/(1024 x HzVorgabe)
IRQ-Presc. = Takte/62
Timervorgabe = 256 - (Takte/IRQ-Presc.)

Takte lässt sich einfacher berechnen, da 1024 als PRescaler bekannt ist:

IRQ-Presc. = 15625 / HzVorgabe

Also 3 mal Teilen und eine Subtraktion ergeben:

- Eine Abweichung von unter 1,4% maximal
- Eine geringere Abweichung bei höherer Taktrate
- Die IRQ erst nach 63488 oder mehr Takten aufgerufen
- Es lassen sich Werte für bis zu 252 Hz berechnen (danach wegen Rundungsfehlern Division/0)

Würde der AVR richtig runden, läge die Abweichung bei maximal 0,8%.