Hat mal jemand auf den AVR ATTiny der Serie 1 einen Input Capture auf
Timer/Counter D, also TCD0 umgesetzt?
Man muss das im datasheet spärlich dokumentierte Event-System
konfigurieren. Wollte ausgehend von einem Flankenwechsel eines Portpins
auf dem TCD0 einen Capture auslösen und dabei einen synchronen
Event-Channel nutzen. Da kann man noch ein Digitalfilter nutzen.
Den Portpin als Event-Generator zu definieren ist kein Problem.
Jetzt finde ich aber weder im Datenblatt noch in den Headerfiles
Hinweise auf einen TCD0 als "Synchronous User".
Oder ist der "Synchronous Event Channel 0" per default immer mit dem
"Input Event A" des TCD0 und der Channel 1 mit dem Event B Eingang
verbunden?
Reine Spekulation, leider steht im DaBla nix darüber.
Eine asynchrone Lösung findet man, damit kann man aber kein Filter
nutzen.
Wulf D. schrieb:
> Man muss das im datasheet spärlich dokumentierte Event-System
> konfigurieren. Wollte ausgehend von einem Flankenwechsel eines Portpins
> auf dem TCD0 einen Capture auslösen und dabei einen synchronen
> Event-Channel nutzen. Da kann man noch ein Digitalfilter nutzen.
>
> Den Portpin als Event-Generator zu definieren ist kein Problem.
>
> Jetzt finde ich aber weder im Datenblatt noch in den Headerfiles
> Hinweise auf einen TCD0 als "Synchronous User".
Der TCD ist ein exotisches Tier, denn er ist von Hause aus asynchron zum
Rest. Er synchronisiert also immer selber auf seine Takt-Domain. Und an
dieser Stelle hat er dann auch eigene Filter. Siehe Blockschaltbild.
Die wesentliche Ausnahme davon ist das direkte "Durchgreifen" auf die
Ausgänge des TCD. Das kann wirklich asynchron erfolgen, dann aber eben
auch nicht gefiltert werden. Das ist aber überhaupt nicht deine
gegenwärtige Spielwiese. Wenn ich dich richtig verstanden habe, willst
du ja nur Capturen.
> Oder ist der "Synchronous Event Channel 0" per default immer mit dem
> "Input Event A" des TCD0 und der Channel 1 mit dem Event B Eingang
> verbunden?
Nö, womit die beiden Input Events des TCD verbunden werden, ist über das
Eventsystem konfigurierbar. Und es ist scheißegal, ob die Quelle in
üblicher Lesart synchron oder asynchron ist, sie muß sowieso mit der
Taktdomain des TCD synchronisiert werden. Ausnahme ist, wie gesagt, die
direkte Steuerung der Ausgabe. Die kann auch wirklich asynchron
erfolgen, wobei asynchron hier doppelt asynchron ist, erstens asynchron
zum IO-Takt (also die übliche Lesart), aber auch asynchron zur
TCD-Taktdomain.
> Reine Spekulation, leider steht im DaBla nix darüber.
Da steht alles darüber. Man muss nur verstehend lesen und nicht nur
überfliegen.
Hallo,
vielleicht hilft dir die App Note 3212 "Getting Started with TCD"
weiter.
https://www.microchip.com/en-us/product/attiny3217#Tools%20And%20Software
Unterhalb bis auf "Seite" 10 vorklicken.
Ob S. schrieb:
> Da steht alles darüber. Man muss nur verstehend lesen und nicht nur
> überfliegen.
Danke für deine Hinweise. Das mit dem asynchronen Output hatte ich auch
so verstanden, aber wie du schon sagtest, brauche ich nicht. Nur
Capture.
Ich hatte das schon mehr als überflogen. Ich halte die Erklärungen noch
immer für stark verbesserungswürdig. Der TCD0 ist wohl immer ein "async
user" im Sinne des Event-Systems. Doof halt wenn da Sätze wie diese
stehen: 1 | It is not possible to use asynchronous event detection and digital filter at the same time.
|
Andere Beispiele:
- die beiden Event-Eingänge werden im TCD0-Kapitel mit "Input Event A"
und "Input Event B" bezeichnet. Aber nur da.
Im EVSYS-Kapitel stehen die mit "Event 0" und "Event 1", ebenso wie in
den Headerfiles.
- Mal heißt das unterste Bit im TCD-Eventregister (TCD0.EVCTRLA) CAPTEI,
mal heisst es TRIGEI.
Ich finde solche Inkonsistenzen nervig, kosten Zeit die richtige
Interpretation zu finden.
Veit D. schrieb:
> Hallo,
> vielleicht hilft dir die App Note 3212 "Getting Started with TCD"
> weiter.
> https://www.microchip.com/en-us/product/attiny3217#Tools%20And%20Software
Danke, das hilft. Die Sache funktioniert nun.
Das Event-System ist eigentlich eine tolle Sache. Man konfiguriert es in
drei Schritten.
- Ein "Generator" auf einen Channel legen. Beispiel Portpin PB4
/* Asynchronous Channel 1 Generator Selection*/ 1 | EVSYS.ASYNCCH1 = EVSYS_ASYNCCH1_PORTB_PIN4_gc;
|
- Den Channel dem "User" zuweisen. Beispiel TCD0 Event 0 select 1 | EVSYS.ASYNCUSER6 = EVSYS_ASYNCUSER6_ASYNCCH1_gc;
|
- Das Event-Register des Users für die gewünschte Reaktion
konfigurieren.
Im Detail lassen sich nur bestimmte Kanäle von Generator zu User legen,
aber wäre mit etwas genauerer Erklärung im DaBla nahezu trivial.
Hallo,
schön das du es lösen konntest. Ich wusste nicht ob es mit dem
Eventsystem oder TCD Probleme gibt. Egal welcher Art. Microchip hält
viele App Notes bereit, leider teilweise über Controller Serien hinweg
verteilt/verstreut. Es lohnt sich über alle neuen ATtiny und AVR Reihen
mal reinzuschauen. Die Hardwareeinheiten sind ja immer ähnlich
aufgebaut. Paar Bsp. hintereinander gibts hier.
https://forum.arduino.cc/t/nano-every-atmega4809-am-anfang-stand-der-anfang/701185
Viele Zusammenhänge was wie möglich ist mittels Eventsystem kann man
übrigens im Headerfile rauslesen. Anhand der Bitkonfigurationen und
Aufteilung der Abschnitte. Klar sollte das eigentlich besser aus dem
Manual ersichtlich sein, naja, man muss sich irgendwie zu helfen wissen.
;-)
Wulf D. schrieb:
> Ich hatte das schon mehr als überflogen. Ich halte die Erklärungen noch
> immer für stark verbesserungswürdig. Der TCD0 ist wohl immer ein "async
> user" im Sinne des Event-Systems.
Jepp, so könnte man das vielleicht zusammenfassen.
> Doof halt wenn da Sätze wie diese
> stehen:
> 1 | > It is not possible to use asynchronous event detection and digital
| 2 | > filter at the same time.
| 3 | >
|
Nein, das ist völlig korrekt, denn diese Aussage bezieht sich ja auf die
allgemein verfügbaren Filter des Eventsystems und nicht auf die
zusätzlich vorhandenen im Spezialfall des TCD. Also völlig korrekt.
> Andere Beispiele:
> - die beiden Event-Eingänge werden im TCD0-Kapitel mit "Input Event A"
> und "Input Event B" bezeichnet. Aber nur da.
> Im EVSYS-Kapitel stehen die mit "Event 0" und "Event 1", ebenso wie in
> den Headerfiles.
> - Mal heißt das unterste Bit im TCD-Eventregister (TCD0.EVCTRLA) CAPTEI,
> mal heisst es TRIGEI.
>
Naja, das ist tatsächlich alles etwas inkonsistent und das völlig ohne
Not. Das hätte man sicher schöner machen können.
> Ich finde solche Inkonsistenzen nervig, kosten Zeit die richtige
> Interpretation zu finden.
Da bin ich voll bei dir.
Hallo,
helfe mir einmal auf die Sprünge? Woher kommt das Bit "CAPTEI" in
TCD0.EVCTRLA bei dir? Ich finde es nicht.
TRIGEI gibt es für TCD.
CAPTEI für TCB.
2 unterschiedliche Timer, 2 unterschiedliche Aufgaben.
Veit D. schrieb:
> Hallo,
>
> helfe mir einmal auf die Sprünge? Woher kommt das Bit "CAPTEI" in
> TCD0.EVCTRLA bei dir? Ich finde es nicht.
>
> TRIGEI gibt es für TCD.
> CAPTEI für TCB.
>
> 2 unterschiedliche Timer, 2 unterschiedliche Aufgaben.
Ahem, nö, da bin ich anderer Meinung. Die Aufgabe ist ja durchaus
dieselbe. Da hätte man die Bits auch locker gleich benennen können, auch
wenn sie zu unterschiedlichen Timern gehören. Wenn denn auch die Nummern
der physischen Bits gleich sind, die sie repräsentieren, was hier ja der
Fall ist.
Aber: Das ist Meckern auf hohem Niveau. Gegen teilweise obszönen
Peripherie-Benennungs-Wallungen bei anderen Architekturen ist das bei
den AVR8 doch immerhin noch wenigstens halbwegs konsistent und
einheitlich. Gegenüber dem doch mitunter recht heftigen Wildwuchs bei
den Classic-Teilen (vor allem bei den Tinys) ist es bei den modernen auf
jeden Fall schon eindeutig besser geworden.
Hallo,
gut, lassen wir so stehen. :-)
Ja ok, sind wirklich zwei unterschiedliche Timer wo das untereste Bit
mit CAPTEI bzw TRIGEI bezeichnet ist. Die Funktion ist gleich.
EDGE macht in beiden Timern auch das gleiche und ist gleich bennant:
geht doch.
Die "Getting Started with ..." sind wirklich gut. Weiß auch nicht warum
ich den zum TCD nicht fand.
Eine Sache klappt noch nicht: will dass der Timer nach dem Capture
automatisch resettet und neu startet. Nach dem Text in Datenblatt sollte
das funktionieren:
1 | /* Example 22-4. Reset One Ramp Mode by Input Event Capture
| 2 | In One Ramp mode, the counter can be reset by an input event capture. To achieve this, use input
| 3 | event B and write 0x08 to the INPUTMODE bit field in the Input Control B (TCDn.INPUTCTRLB)
| 4 | register.*/
| 5 | TCD0.INPUTCTRLB = 0x08;
|
Habe ich auch gemacht, aber der läuft mir noch jedesmal in den Overflow,
obwohl der da niemals ankommen dürfte.
Wulf D. schrieb:
> Eine Sache klappt noch nicht: will dass der Timer nach dem Capture
> automatisch resettet und neu startet. Nach dem Text in Datenblatt sollte
> das funktionieren:
>
> 1 | > /* Example 22-4. Reset One Ramp Mode by Input Event Capture
| 2 | > In One Ramp mode, the counter can be reset by an input event capture. To
| 3 | > achieve this, use input
| 4 | > event B and write 0x08 to the INPUTMODE bit field in the Input Control B
| 5 | > (TCDn.INPUTCTRLB)
| 6 | > register.*/
| 7 | > TCD0.INPUTCTRLB = 0x08;
| 8 | >
|
>
> Habe ich auch gemacht, aber der läuft mir noch jedesmal in den Overflow,
> obwohl der da niemals ankommen dürfte.
Bleibt eigentlich nur zwei Fragen:
1) Bist du überhaupt im One-Ramp-Mode? Nur dafür wird diese Funktion
versprochen.
2) Wie genau hast du sichergestellt, dass garantiert in jedem
Timerzyklus mindestens ein Capture-Event auftritt?
Ob S. schrieb:
> Bleibt eigentlich nur zwei Fragen:
>
> 1) Bist du überhaupt im One-Ramp-Mode? Nur dafür wird diese Funktion
> versprochen.
Ja, das ist der default und den habe ich nicht verändert.
> 2) Wie genau hast du sichergestellt, dass garantiert in *jedem*
> Timerzyklus mindestens ein Capture-Event auftritt?
Habe hier einen kleinen Testaufbau mit einem Generator der die Events
produziert.
Fehler habe ich gefunden, hatte den Inputmode nach dem ENABLE des TCD0
gesetzt, was dann nicht übernommen wird. Hätte man im Datenblatt sehen
können.
Jetzt habe ich es richtig gemacht, aber dann lese ich das
CAPTUREB-Register immer mit 0x000. Hatte gehofft, dass vorm Reset des
Counters noch ein Übertrag ins CAPTURE-Register erfolgt. Ist offenbar
nicht so.
Dann bleibt vermutlich nur ein Workaround, dass ich die Differenz der
CAPTURE-Werte von aufeinander folgenden Ereignissen rechne. Geht auch.
Hallo,
soviel habe ich mit TCD noch nicht gemacht. Denkbar wäre, wenn ein
Capture Ereignis eintritt, dass CaptureA/CaptureB Register auszulesen.
Das sollte mit einer Interrupt Routine für das "Ereignis Flag" machbar
sein. Zumindestens macht der Text zu Kapitel CAPTURE A und CAPTURE B die
Hoffnung. 22.5.19.
Sollte ähnlich funktionieren wie beim capturen mit TCB.
Was möchtest du denn überhaupt mit TCD machen?
Hallo,
ich denke mal, dass der TCD in erster Linie zur Erzeugung von
Steuersignalen für Motorsteller und Schaltregler ausgelegt ist. Dafür
bietet der ja beste Vorraussetzungen.
Ist genau so wie du schreibst umgesetzt, in der Event-ISR
(TCD0_TRIG_vect) werden die CAPTURE Register gelesen. Die werden
übrigens nach dem Triggern so lange eingefroren, bis man die ausliest.
Das Trigger-Event kommt, der entsprechende Interrupt wird ausgelöst,
aber im CAPTURE-Register steht nichts (mehr) drin.
Aber wie gesagt, ich kann problemlos auf den automatischen Counter-Reset
verzichten und Differenzen bilden. Muss nur eine Fallunterscheidung
wegen Counter-Überlauf treffen.
Ich will mit dem TCD über Hallsensoren, die an zwei Portpins hängen,
u.a. die Drehzahl einer Maschine bestimmen. Gleichzeitig soll einer der
Hallsensoren den TCA starten, der drehzahlabhängig weitere Steuersignale
mit zeitlichem Abstand erzeugt.
Ich hatte das früher schon mal mit einem ATTiny85 gemacht, aber da
benötigen einige Trigger SW dazwischen, so dass es unerwünscht jittert.
Dessen 8-Bit Timer-Auflösung ist auch grenzwertig.
Mit dem ATtiny1616 sollte es rein signalbasiert funktionieren, außerdem
verspreche ich mir von den Hallsensoren mehr Präzision als von einem
zuvor verwendeten Induktivgeber.
Habe den TCD verwendet, weil der im Gegensatz zum TCB einen Vorteiler
hat. Und der TCA bereits in der HW mit seinem Output Compare-Ausgang WO0
verschaltet ist.
Wäre mit aktuellem Wissensstand wahrscheinlich umgekehrt einfacher
umzusetzen.
Datasheet:
"The Timer/Counter type D (TCD) is a high-performance waveform
generator...
... can run on a clock that is asynchronous to the peripheral clock...
... generates two independent outputs with optional dead-time."
TCB: "measurement of digital signals"
Hallo,
das wissen wir, dennoch kann man paar Dinge ausprobieren.
Hätte zur Drehzahlmessung sicher auch den TCB nehmen können. Hatte mich
vom fehlenden Vorteiler abschrecken lassen, aber man kann den Vorteiler
vom TCA einspannen. Dank 16 Bit Auflösung der Zähler ginge das auch.
Wie so oft, viele Wege führen nach Rom.
Hallo,
@ Wulf
liest du die Capture Register A/B immer erst mit dem Low Byte und dann
High Byte aus? Wenn beide gelesen werden sollen, dann erst von beiden
das Low Byte, dann A High, dann B High.
Hier die ISR: 1 | ISR (TCD0_TRIG_vect)
| 2 | {
| 3 | dummy = TCD0_CAPTUREB;
| 4 | if (dummy>captalt) capt = dummy-captalt;
| 5 | else capt= 0x1000+dummy-captalt;
| 6 | captalt=dummy;
| 7 | states |= (1<<s_drehz);
| 8 | TCD0.INTFLAGS = TCD_TRIGB_bm;
| 9 | }
|
Nach dem ersten Lesezugriff wird das Capture-Register zurückgesetzt,
deshalb muss man es retten (dummy). Das Differenz-Ergebnis steht nach
der Fallunterscheidung in uint16_t capt. Alle Variablen sind uint16_t.
> vom fehlenden Vorteiler
Der ATtiny1616 hat 2x TCB.
Und beim ATtiny1626 kann man die sogar kaskadieren.
(Datasheet: " • 32-bit capture")
Hallo,
@ Wulf
okay, wenn das klappt dann ist gut. Ich dachte es hätte noch ein Problem
gegeben. Ich wünsche noch viel Spass am ggf. tüfteln mit den neuen
ATtinys.
AVR32EA32-I/RXB
VQFN-32 5×5mm
Two 16-bit Timer/Counters type A (TCA)
Four 16-bit Timer/Counters type B (TCB)
(DigiKey: 1,04 € + MwSt.)
Funktioniert jetzt alles. Die neueren AVR machen schon Spaß bei harten
Echtzeitanwendungen und kosten dabei praktisch nichts.
Das UPDI Debug Interface ist auch ein Fortschritt. An die QFN Gehäuse
kann man sich gewöhnen, wobei es auch Alternativen gibt.
Nur die Qualität der Datenblätter war gefühlt früher besser, da
konsistenter und ausführlicher.
Hallo,
das Thema Datenblatt scheint im Forum sehr unterschiedliche Auffassungen
zu haben. :-) Ich finde bspw. die Zusammenfassung aller Register je
Hardwareinheit mit allen Bits sehr gut. Den Screenshot von hier meine
ich. Beitrag "Re: AVR ATtiny Serie 1: Input Capture TCD0"
Kennt man die Einheit benötigt man fast nur noch diese Tabelle.
In den alten Manuals sind die Register über viele Seiten verstreut ohne
jede Zusammenfassung der Hardwareinheit. Da musste man alles
zusammensuchen. Die Beschreibung der Einheiten könnte durchaus mit paar
Sätzen mehr ausführlicher sein. Das stimmt wiederum. Mit allen für und
wider lese ich lieber die neuen statt alten Manuals. Wie gesagt, dass
scheint im Forum Geschmackssache zu sein und eben so viel Gewohnheit.
Bis auf den fehlenden kompletten Satz an Prescalern für TCB habe ich an
den neuen Controllern nicht auszusetzen.
Wegen den RegisterNamen und BitNamen. Wir müssten ein Forum eigenes
Headerfile schreiben. So wie uns das passt. :-) :-) :-)
Die Marktmacht des Forums setzt sich durch. :-) :-) :-)
Quasi ein Fork der zur Außenwelt nicht kompatibel ist.
Jetzt höre ich auf. :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|