ich bastel gerade an meinen Arduino Uno sowas wie einen Drehgeber ran. Ich habe als "Best-Practice" jetzt das hier gefunden: Drehgeber – Mikrocontroller.net und möchte das auch verwenden.
Den Code habe ich jetzt ein bisschen angepasst, allerdings scheitere ich hier an drei Zeilen:
Gemeckert wird hier, dass TCCR0, OCR0, TIMSK und OCIE0 unbekannt sind ("Der Bezeichnier 'TCCR0' ist nicht definiert"). Das sind ja, wenn ich das richtig weiß Register des µC's und da hörts bei mir einfach auf. Evtl. kann mir da wer unter die Arme greifen.
Übrigens wird auch über XTAL gemeckert. Das ist der Takt in Hz. Gibt's dazu irgendwie eine Entsprechung, die ich verwenden kann um den Takt aus der Konfigurationsdatei herauszuziehen? Oder muss ich mir das definieren und dann aufpassen, wenn ich die Hardware wechsel?
Die Register musst du auf deinen Controller anpassen. Das unterscheidet sich manchmal leicht. Vor allem zwischen Atmega8/16 und den späteren Atmegas oder den AtTiny. Siehe Datenblatt. Da ist alles aufgelistet.
TIMSK (timer interrupt mask) gibt es z.B nicht. Also ein Register für alle Timer. Auf den neueres Prozessoren hat jeder Timer sein eigenes Register dafür. Außerdem gibt es mehrere TCCR (timer counter control register) und OCR Register pro Timer. Da schaut man dann nach in welchem Register die Bits stehen die man ändern will.
Timer0 solltest du auf dem Arduino aber nicht verwenden. Der wird für millis() gebraucht. Timer1 oder Timer2 geht aber.
Ich bin halt gerade mobil unterwegs, da kann ich nicht testen und ein fettes Datenblatt will ich jetzt auch nicht ziehen. Sollte ich daheim mal machen und mir dann hier rüberschieben
Wenn das soweit funktionieren sollte, bräuchte ich nur noch idealerweise eine Möglichkeit den Takt (XTAL) aus der Konfigurationsdatei zu bekommen.
Hardwarewechsel ist bei mir nämlich meistens eher Taktwechsel, nämlich vom Uno-Board rüber auf den blanken Chip mit aktiviertem internen Takt.
Und hier musst du dann wirklich ins Datenblatt schauen! Die Clock Select Bits sind bei Timer1 im TCCR1B Register.
Außerdem sind die Modi anders! Der Timer soll im CTC Modus laufen. Das ist dann WGM12. Das steht auch in TCCR1B. In TCCR1A sind nur WMG10 und WMG11
Die Timer funktionieren grundlegend gleich. Aber es gibt auch auf dem gleichen Prozessor kleine Unterschiede zwischen Timer0, Timer2 und Timer1/3/4/5 (3-5 nur auf dem Mega)
Den Takt bekommt du auf dem Arduino glaube ich mit F_CPU
wenn du [u]delay()[/u], [u]millis()[/u] und [u]micros()[/u] verwendest, solltest du Timer 0 nicht selbst verwenden.
Dann eher Timer 2.
Und dann bitte immer beim setting vom Timer erstmal alle Timer-Register löschen beim Arduino, weil die sonst vorbelegt sind, anders wie man denkt.
Peter definiert XTAL, eigentlich ist F_CPU Standard.
Tommy56:
Interessiert immer, man wird nicht dümmer dadurch
Gruß Tommy
Gerne doch!
Bei mir liegen die Dateien im Verzeichnis: E:\Programme\Arduino\hardware\arduino\avr\cores\arduino
Verändert wird wiring.c. hier ein Ausschnitt:
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}
timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
if(SystemTick) SystemTick(); // // <<--------------
}
@ combie, dass ist also deine ATtiny Version von millis?
? ? ?
Nee...
Ja... (auf meinen Tiny85 tuts das unverändert)
Entstanden ist das, weil ich einen "Tick" brauchte, aber schon alle Timer mit irgendwas belegt waren. Und in loop() blockierende Dinge erledigt wurden. Seriell und I2C Gedöns.
kurzes Feedback: ich hab der Einfachheit halber die TimerOne-Lib verwendet.
Mit dem Ergebnis, dass die gepostete Variante einfach nicht funktioniert hat. Und ja: ich habe mich da auf Fehlersuche begeben, die Hardware funktioniert, der Arduino bekommt die Signale, auch der Timer-Interrupt wird regelmässig aufgerufen. Zählt aber einfach nicht.
Ich hab's dann nach ein paar Stunden bleiben lassen und habe die klassische Variante "Wenn Pegelwechsel am Interrupt, guck was das andere Signal gerade für einen Wer hat" verwendet.
Funktioniert auch, und ich kann mich mit meinem eigentlichen Projekt beschäftigen.