Bei atMega8 anpassen kann.
ich habe einen Drehgeber mit
1000 Impulse pro Umdrehungen
und maximal 10 000 Drehzahl pro min.
und dafür dachte ich eine XTAL = 16e6 und eine Abfrage Zeit von mehr als
1 ms.
Welche prescaler kann ich nehmen? (TCCR0)
Bitte um Hilfe, die Sache sind noch neue für mich
danke
Von welchem µC nach Atmega8 willst du anpassen?
> TCCR0 = 1<<WGM01^1<<CS01^1<<CS00; // CTC, XTAL = 8e6 / 64> OCR0 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5); // 1ms
Die Formel würde auch für andere Prescalerwerte als 64 und andere Zeiten
als 1e-3 Sekunden funktionieren...
Aufpassen musst du, dass bei OCR0 kein Wert > 8-Bit rauskommt, weil
Timer0 nur 8-Bit breit ist. Wenn OCR0 zu groß wird, kannst du entweder
den Prescaler erhöhen oder einen 16-Bit Timer benutzen.
> ich habe einen Drehgeber mit> 1000 Impulse pro Umdrehungen> und maximal 10 000 Drehzahl pro min.
Sind das die Maximalwerte, die der Drehgeber mechanisch und elektrisch
kann (für die der Hersteller garantiert) oder sind das die Werte deiner
Anlage? Willst du so schnelle Drehzahlen messen oder willst du in einem
anderen Bereich messen?
gast schrieb:
> Bitte um Hilfe, die Sache sind noch neue für mich
Dann wirds Zeit, das Funktionsprinzip eines Timers zu verstehen.
Das ist eigentlich ganz simpel.
Der Timer zählt normalerweise von 0 bis 255, weil er ein 8-Bit Zähler
ist. Man kann den Timer jetzt anweisen, bei bestimmten Ereignissen einen
Interrupt zu generieren. Zb. kann man ihm sagen, wenn er bei 255 ist und
wieder auf 0 gehen würde soll er einen Overflow Interrupt auslösen.
Wie schnell zählt denn der Timer?
Das hängt von der CPU-Taktfrequenz und vom Vorteiler ab.
Ist zb die CPU.Taktfrequenz 1MHz und der Vorteiler 1, dann zählt der
Timer auch mit 1Mhz oder anders ausgedrückt: er würde in 1 Sekunde von 0
bis 1000000 zählen. Wenn er könnte. Er kann natürlich nicht, denn bei
255 ist ja Schluss und es kommt ein Overflow und er beginnt wieder bei
0.
Wieviele derartige Overflows gibt es in 1 Sekunde?
Ganz einfach. Logischerweise sind das 1000000 / 256 = 3906. Du kriegst
also 3906 Overflows in der Sekunde, oder anders ausgedrückt 1/3906 =
alle 0.000256 Sekunden (=0.256 Millisekunden) einen.
Benutzt du einen Vorteiler von 8, dann zählt der Timer nicht mehr mit
den vorgegebenen 1MHz sondern mit 1MHz / 8 = 125kHz. Wie sieht dann die
Rechnung aus? Bis 125000 würde er zählen, wenn er könnte. Wenn alle 256
Takte wieder bei 0 angefangen wird, macht das 125000 / 256 = 488
Overflows, oder 1/488 = 0.002 Sekunden (=2 Millisekunden) von einem
Overflow zum nächsten. Durch den Vorteiler ist also die Zeit zwischen 2
Overflow Interrupts von 0.256 Millisekunden auf rund 2 Millisekunden
angewachsen.
Nun ist ein Overflow nur eine Möglichkeit. Es gibt auch noch andere (je
nach Timer). Zum Beispiel kann man den Timer anweisen, nicht immer bis
255 zu zählen, bis etwas passiert, sondern man kann ihm auch einen
Endstand (der dann bei einem 8-Bit Timer klarerweise kleiner als 256
sein muss) vorgeben, bis zu dem er zählen soll.
Mal angenommen, du gibst ihm vor: 1Mhz, Vorteiler 1, Zählerendstand: 99
Wie sieht dann die Rechnung aus?
Der Timer würde bei einem Vorteiler von 1 wieder in 1 Sekunde von 0 bis
1000000 zählen, wenn er könnte. Kann er aber nicht, bei 99 ist Schluss
(so hast du es ihm ja vorgegeben). Wieviele Overflows hast du daher
jetzt?
1000000 / 100 = 10000. Von einem Overflow zum nächsten vergehen daher
1/10000 = 0.0001 Sekunden (0.1 Millisekunden). Interessant nicht wahr.
Gegenüber oben hast du nur den Endwert des Timers, bis zu dem er zählen
darf verändert. Und da der Timer nicht mehr soweit zählen darf, kommen
natürlich auch die Overflows viel häufiger.
Das war doch nicht schwer, oder?
Jetzt bist du sicher auch in der Lage, die Berechnung zu verstehen, die
Peter da benutzt und sie an deine Verhältnisse anzupassen. Gleich
nachdem du rausgefunden hast, dass der Timer0 eines Mega8 kein OCR0 und
damit auch nicht die Möglichkeit hat, einen vorzeitigen Overflow
auszulösen :-)
gast schrieb:
> @stefan>> ja so schnelleren Drehzahlen will ich messen.
Dann mache eine Fehlerabschätzung um die benötigte Messzeit heraus zu
finden.
10000 rpm sind 166,667 Umdrehungen/s
*1000 Impuls/Umdrehung => 166667 Impulse/s (6 µs/Impuls)
In 1ms würde man 166 Impulse zählen und 0,667 nicht. Das wäre ein Fehler
von 0,4% (=> 10000 - 40 rpm). 166 Impulse passen gut in einen
8-Bit-Wert.
In 2ms würde man 333 Impulse zählen, d.h. man braucht bereits einen
16-Bit-Wert. Der Fehler wäre 0,334 / 333 = 0,1% (=> 10000 - 10 rpm).
Zur Ausnutzung des 16-Bit Zählers könnte man die Messzeit auf
65535/166667 = ~393,2ms ausdehnen. Dann bekäme man einen Fehler von
~0,03% (=>10000 - 3 rpm)
>> ich möchte der Code von Peter für meinem Drehgeber (atmega8) anpassen...> In 1ms würde man 166 Impulse zählen
Nein, mit einem Abtastintervall von 1 ms würde man 165 Impulse verpassen
:-(
Oder im Umkehrschluss:
die Abtastfrequenz muß mindestens 1/167 ms sein, also müsste spätestens
alle 6us ein Interrupt ausgeführt werden. Das ist sehr sehr
grenzwertig...
Lothar Miller schrieb:
>>> ich möchte der Code von Peter für meinem Drehgeber (atmega8) anpassen...>> In 1ms würde man 166 Impulse zählen> Nein, mit einem Abtastintervall von 1 ms würde man 165 Impulse verpassen
Abtastintervall und Messzeit unterscheide ich. Wenn der Timer bei jedem
Interrupt einen Eingang abtastet, hast du Recht, dass 1ms Intervalle
dazwischen viel zu lang sind. Unter der Messzeit verstehe ich die Zeit
in der ein Hardwarezähler an einem Eingang des AVRs aktiv ist (sog.
Torzeit).
@stefan
>Zur Ausnutzung des 16-Bit Zählers könnte man die Messzeit auf>65535/166667 = ~393,2ms ausdehnen. Dann bekäme man einen Fehler von>~0,03% (=>10000 - 3 rpm)
bitte kennst du einer 16-Bit Zählers die du mir empholen kannst?
>In 2ms würde man 333 Impulse zählen, d.h. man braucht bereits einen>16-Bit-Wert. Der Fehler wäre 0,334 / 333 = 0,1% (=> 10000 - 10 rpm).
Peter hat in seiner code der Timer0 compare benutzt bei Atmega8 finde
ich nur der Timer Counter2 Match als Ersetzung, leider ist er
8-bit-wert.
wie kannt ich das umgehen
vielen dank
Stefan B. schrieb:
> Abtastintervall und Messzeit unterscheide ich.
Richtig, aber es geht hier noch gar nicht um die Messung, sondern erst
mal um die Abtastung, weil kein Hardwarezähler vorhanden/verwendet
ist.
Leider hat ein AVR keine Eingänge, die ein Quadratursignal (incl.
Richtung) direkt auswerten könnten. Aber wenn es nur um die Drehzahl
geht, und die Drehrichtung egal ist, dann könnte einfach ein
Hardwarezähler verwendet werden.
EDIT:
> Peter hat in seiner code der Timer0 compare benutzt bei Atmega8 finde> ich nur der Timer Counter2 Match als Ersetzung, leider ist er> 8-bit-wert.
Mir scheint, hier kommt was durcheinander:
Peter verwendet den Counter als Zeitgeber.
gast verwendet den Counter als Impulszähler.
"Man muss die ursprüngliche Fragestellung rauskitzeln und dann die beste
Methode finden, um die Aufgabe zu lösen."
Angenommen es geht um die Ermittlung der Drehzahl im 10000 rpm Bereich
mit einem Impulsgeber (physikalisch ein Drehgeber) mit 1000
Impulsen/Umdrehung. Das Grundproblem ist dann eine Frequenzmessung bis
167 kHz und für solche Frequenzmessungen gibt es sehr viele
Beispielprojekte.
Dann kann ein System aus Torzeit und Hardwarezähler verwendet werden.
Für die Torzeit einen AVR-internen Timer und für den Zähler einen
AVR-internen Counter. Welche Kombination 8/8 8/16 16/8 oder 16/16 muss
man sich ansehen. Da hilft das Datenblatt. Die Frequenz (Drehzahl)
ergibt sich aus f = Impulse/Torzeit.
Man kann auch versuchen, die Zeit zwischen den Impulsen direkt zu messen
und die Frequenz (Drehzahl) über f=1/Zeit zwischen Impulsen zu
berechnen. Ich vermute(!): Die von Lothar berechneten 6µs sind bei bei
einem AVR mit 16 MHz noch messbar, allerdings mit >~1% (+-100rpm)
Fehler. Die notwendigen Zeitstempel könnte man sich eventuell von der
Input Capture Einheit im AVR geben lassen.