ich suche , wie im Betreff geschrieben , eine Möglichkeit beim STM32F411
die HW-counter für Step/Dir Signale zu realisieren (5 Stück !).
Es geht um das Lesen der Signale für die Steuerung einer
5-Achs CNC Fräsmaschine. (5 Step/Dir Signale mit max. 250 kHz)
Derzeit mache ich es mittels ext. Interupt möchte aber die Möglichkeit nutzen die Timer 1,2,3,4,5 zu verwenden , ähnlich den HW-Countern für
Quadrature Encoder.
Diese hab ich getestet , laufen perfekt mit den A/B Signalen von den Encodern.
Gibt es eine Möglichkeit die Timer Register so zu konfigurieren dass sie auch mit STEP/DIR Signalen so problemlos umgehen können ?
Ich finde keine Möglichkeit das Richtungssignal einzubinden um den Counter
ab- , bzw. aufwärts zählen zu lassen.
Bin für jede Hilfe dankbar.
Ich benutze MikroBasic , erhalte leider im MikroE Forum keinerlei Hilfe zu dem Thema.
danke für den Hinweis , den Beitrag kenne ich bereits.
Würde für den Fall , wenns wirklich keine Möglichkeit mittels HW-counter
beim STM32 gibt , ein paar AVR's verwenden.
Würde für den Fall , wenns wirklich keine Möglichkeit mittels HW-counter
beim STM32 gibt , ein paar AVR's verwenden.
Bei 250 kHz mußt Du die in Assembler programmieren und per IIC auslesen.
Eine kompakte Lösung wäre mit einem Pico-Board mit RP2040 möglich.
Reicht Dir denn der relative langsame Zugriff per IIC-Bus?
Oder anstatt diskreter Logik ein 8-pol. AVR zur Umsetzung Step/Dir -> PhaseA/PhaseB verwenden und dann auf die STM-Timer geben.
Oder anstatt diskreter Logik ein 8-pol. AVR zur Umsetzung Step/Dir ->
PhaseA/PhaseB verwenden und dann auf die STM-Timer geben.
Genau so hab ich es vor wenn es keine interne Möglichkeit im STM32 gibt.
Die AVR's in Assembler für die Wandlung Step/Dir --> A/B zu programmieren,
da sehe ich kein Problem.
Jedoch kann ich es kaum glauben dass die Timer des STM32 bei der Vielfalt an Möglichkeiten nicht zu konfigurieren sind um STEP/DIR zu lesen.
Warscheinlich sehe ich den Wald vor lauter Bäumen nicht .... oder so ähnlich.
Außerdem beschäftige ich mich erst seit 2 Wochen mit dem 32bitter , also
bin da recht neu dabei. (hobbymäßig..)
Genau so hab ich es vor wenn es keine interne Möglichkeit im STM32 gibt.
Die AVR's in Assembler für die Wandlung Step/Dir --> A/B zu
programmieren,
da sehe ich kein Problem.
Da wäre ich bei 250kHz VORSICHTIG. Ausser für unserem heldenhaften C-hater ist das auch in ASM schon sportlich. Aber vor allem, warum? Sind ZWEI kleine CMOS-ICs / Kanal zuviel? Es reichen sogar weniger, siehe Anhang! 9 Stück für 5 Kanäle.
Jedoch kann ich es kaum glauben dass die Timer des STM32 bei der
Vielfalt an Möglichkeiten nicht zu konfigurieren sind um STEP/DIR zu
lesen.
Beim ATXmega kann man die IOs so konfigurieren, daß man damit steigende und fallende Flanken erkennt und Hardware-Events auslöst, welche direkt den Timer ansteuern. Vermutlich können das auch die STM32.
Warscheinlich sehe ich den Wald vor lauter Bäumen nicht .... oder so
ähnlich.
Jedoch kann ich es kaum glauben dass die Timer des STM32 bei der
Vielfalt an Möglichkeiten nicht zu konfigurieren sind um STEP/DIR zu
lesen.
Wenn man genauer hinsieht, sind die Möglichkeiten doch begrenzt, wie auch andere Sachen bei den STM32. Es fällt meist erst dann auf, wenn man gezielt eine Lösung braucht.
Wenn Du den F411 erst kurz kennst, plane die Verwendung der IO-Pins sorgfältig, damit Du die benötigte Peripherie auch voll nutzen kannst.
Die AVR's in Assembler für die Wandlung Step/Dir --> A/B zu
programmieren,
da sehe ich kein Problem.
Mit einem guten C-Compiler ginge das vielleicht auch schon. Es wäre einen Versuch wert - aber nicht bei schönem Sonnenwetter ;-)
Beim ATXmega kann man die IOs so konfigurieren, daß man damit steigende
und fallende Flanken erkennt und Hardware-Events auslöst, welche direkt
den Timer ansteuern. Vermutlich können das auch die STM32.
Damit kannst du Zählen, aber nicht zusätzlich mit einem zweiten Pin die Zählrichtung umzuschalten. Für das Umschalten wird man um einen Interrupt und eine paar Zeilen Programmcode wohl nicht drumherum kommen, wenn man nicht noch etwas zusätzliche Hardware spendieren will.
Die Wahrscheinlichkeit das es sowas fertig gibt dürfte arg gering sein weil es wohl keinen Sensor gibt er sowas ausgibt und eine µC das verarbeiten/zählen müsste. Zur Kommunikation zwischen zwei µC wäre sowas als Protokoll noch absurder. Gray-Code ist dagegen recht gebräuchlich und wird daher auch von etlichen µC in Hardware unterstützt.
Hallo Mi N.,
danke für deine Mühe.
Das in Assembler für den AVR zu programmieren , damit hab ich kein Problem.
Werde ich auch machen falls es beim STM32 keine Möglichkeit gibt.
Wäre halt (warscheinlich) zu schön gewesen , Kabel anstecken und läuft....
Mich hat einfach selber interessiert, ob man es bei hinreichender Ausführungszeit noch in C formulieren kann.
Bleibt noch offen, ob Dir die teilweise nur 16 Bit breiten Zähler im F411 auch reichen. Diese per Software zu vergößern könnte wegen up/down-Richtungswechsel heikel werden. Packt man die Zähler in einen kl. AVR sind 32 Bit kein Problem, der Zugriff per IIC dauert aber deutlich länger.
Die war aber sehr klein, weshalb ein Test entfallen mußte
Folglich werden in Zeile 21 noch + und - Flanken erkannt. Das muß noch
angepaßt werden, erhöht die Laufzeit aber nur minimal.
Ja. Aber man sollte nicht nur die Abtastung in der Schleife machen, auch den alten Wert kopieren. Eher so.
1
while(1){
2
do{
3
alt_step=temp;
4
temp=PINB;
5
}while(temp&~alt_step&BIT(STEP));// auf +Flanke von STEP warten
Klar, wenn man vor weiß, da STEP auf LOW ist, muss man nur prüfen, ob es jetzt HIGH ist. Geht einfacher und schneller, erst recht in ASM. Aber bleibt das Problem, daß man DIR zur richtigen Zeit abtasten muss, um es dann auszuwerten. Naja, da hier noch Luft ist, sollte man es mit der Microoptimierung nicht übertreiben und eher auf Nummer sicher gehen.
Bleibt noch offen, ob Dir die teilweise nur 16 Bit breiten Zähler im
F411 auch reichen. Diese per Software zu vergößern könnte wegen
up/down-Richtungswechsel heikel werden.
Das hab ich bereits per Overrun/Underrun Interrupt gelöst, funktioniert einwandfrei.
Geht es nur ums Mitschreiben, oder sollen die Signale im STM32F411
erzeugt werden?
Der STM32F411 muss (soll ;-) ) folgendes machen:
5x Step/Dir Signale einlesen --->
Im Hauptprogramm werden diese Werte verrechnet , dh. es wird die Nullpunktverschiebung der X,Y u. Z Achse in Bezug auf die Drehwinkel der
A- u. C-Achse berechnet (nennt man TCPM oder RTCP )
Daraus resultierend werden dann wieder STEP/DIR Signale für die 5 Endstufen
generiert und in (fast) Echtzeit ausgegeben.
Derzeit lese ich die 5x STEP/DIR Signale mittels Interrupt ein, das frisst aber zuviel an Ressourcen. Der Debugger von MikroE sagt mir dass er ca. 120 Takte braucht um in die ISR rein u. raus zu kommen.
Deswegen muss das im Hintergrund ablaufen. Wenns eben nicht anders geht dann mit zus. AVR's od. Logic IC's über die quadratur Encoder Eingänge.
Dann hab ich genug Zeit für die trigonometrischen Berechnungen frei.
Wenn's nur ein Kanal wäre, könnte man STEP auf zwei Timer geben, einen davon im gated mode mit DIR. Mit ein wenig Mathematik kann dann der gewünschte Wert berechnet werden. Beim Auslesen muß man aufpassen, daß nicht ein STEP dazwischenfunkt, z.B. indem man in einer Schleife Zähler A, B und wieder A ausliest, bis man zweimal denselben Wert für Zähler A liest.
Leider ist das nicht auf 5 Kanäle skalierbar, weil das Routing für die Zählereingänge doch arg beschränkt ist und die STM32F4-Serie eh nur 8 Zähler hat.
Sind alle Eingänge an einem Port, daß Du die Dekodierung direkt parallel
mit allen Pins gleichzeitig in einem Datenwort machen kannst?
Unsinn. Es gibt eine solide Lösung mit externer Hardware. Da muss man keine Handstände und Krampfaktionen in der Software machen und kann die CPU zu 100% mit sinnvollen Aufgaben auslasten. Problem gelöst.
hab mal einen Arduino Nano mit Bascom/ASM programmiert.
Der soll die 5 Stp/Dir Kanäle einlesen und Quadrature Signale ausgeben.
Läuft am Simulator , kann aber erst heute abend testen.
Dann kannst Du Dir ordentlich auf die Schulter klopfen, daß Du es schaffst, die CPU 100% mit sinnvollen Dingen zu beschäftigen! Ich habe meistens so eine Auslastung um 10...60%.
hab mal einen Arduino Nano mit Bascom/ASM programmiert.
Schau mal was dort oben steht! Längere Quelltexte als Anhang!
Der soll die 5 Stp/Dir Kanäle einlesen und Quadrature Signale ausgeben.
Läuft am Simulator , kann aber erst heute abend testen.
Ohje, ASM im BASIC Compiler 8-0
Das ist alles deutlich langsamer als meine Version. Und wenn die Takte gleichzeitig kommen, wird es nochmal langsamer. Es reicht nicht, wenn es prinzipiell funktioniert, es muss auch SICHER bei maximaler Last funktionieren. Man kann vieles in Software machen, aber nicht alles.
hab mal einen Arduino Nano mit Bascom/ASM programmiert.
Der soll die 5 Stp/Dir Kanäle einlesen und Quadrature Signale ausgeben.
Wir wissen nicht, welche Achsen zu welcher Zeit welche Ausgangssignale liefern. Vielleicht hast Du ja Glück und Deine Lösung reicht Dir aus. Mich wundert auch ein wenig, daß es zuvor allein per Software gelaufen ist.
Selber würde ich die Lösung niemals in nur einen einzigen ATmega328 packen.
Bleibt noch offen, ob Dir die teilweise nur 16 Bit breiten Zähler im
F411 auch reichen. Diese per Software zu vergößern könnte wegen
up/down-Richtungswechsel heikel werden.
Das hab ich bereits per Overrun/Underrun Interrupt gelöst, funktioniert
einwandfrei.
Die F411 Timer arbeiten nicht alle gleich. Insbesondere werden die Interrupt-Flags eines Timers nicht immer über einen einzigen ISR-Vektor verarbeitet. Die NVIC-Priorität kann man passend einstellen, die ISR-Vektoren haben jedoch eine feste Priorität, was genau verkehrt herum sein kann. Weder kenne ich Deine Software noch möchte ich hier dramatisieren, daher nur dieser Hinweis.
Wenn alles einwandfrei funktioniert, ist es gut. Und wenn es Aussetzer gibt, sind die sicherlich so selten, daß sie nur alle paar Stunden auftreten ;-)
Das sollte doch für einen STM32 kein Problem sein.
Interrupts für Überlauf und Unterlauf der Timer aktivieren. Interrupt für jedes Dir-Signal aktivieren und die Stepsignale an die Counter dran.
Bei einem "dir-Interrupt" entsprechend die Richtung des Counters einstellen. Fertig.
So oft ändert sich ja die Richtung nicht, so dass diese paar Interupts nicht ins Gewicht fallen.
Bei einem "dir-Interrupt" entsprechend die Richtung des Counters
einstellen. Fertig.
Wir wissen nicht, wieviele ns zwischen der Änderung von DIR und dem nächsten STEP minimal vergehen. Wir kennen nur den Abstand zwischen zwei gleichsinnigen STEP-Flanken.
Wir wissen nicht, wieviele ns zwischen der Änderung von DIR und dem
nächsten STEP minimal vergehen. Wir kennen nur den Abstand zwischen zwei
gleichsinnigen STEP-Flanken.
Leider habe ich dazu auch keine Info , bzw. nicht die Mittel dies zu messen.
Der step Impuls ist 12 ns breit.
Wenn STEP und Dir gleichzeitig gesetzt werden und auf die fallende Flanke
von STP getriggert wird (aktiv high) müsste das laufen.
Das sollte doch für einen STM32 kein Problem sein.
Interrupts für Überlauf und Unterlauf der Timer aktivieren. Interrupt
für jedes Dir-Signal aktivieren und die Stepsignale an die Counter dran.
Bei einem "dir-Interrupt" entsprechend die Richtung des Counters
einstellen. Fertig.
So oft ändert sich ja die Richtung nicht, so dass diese paar Interupts
nicht ins Gewicht fallen.
Jetzt habe ich doch noch ins Datenblatt gesehen.
Dort gibt es nur ein gemeinsames Flag UIF, was bei Über- und Unterlauf gesetzt wird. Die ISR muß daher noch nachsehen, was zu tun ist und hoffen, daß sich zwischendurch nichts verändert hat.
Die Annahme, daß sich die Richtung nur eher selten ändert, ist mir zu optimistisch. Es kann ja alles so funktionieren, wie Du geschrieben hast, hängt aber doch von den (derzeit unbekannten) Eingangssignalen ab.
Timer 2 - 5 haben nur einen ISR-Vektor. Da kann man Richtungsumschaltung über einen CC-Interrupt auslösen und UIF nach Bedarf verwerten.
Bei Timer 1 hat 'TIM1_UP_TIM10' höhere Priorität als 'TIM1_CC'. Hier kann es Probleme geben. Es kann sinnvoll sein, UIF durch ein CC-Flag zu ersetzen, um nur einen Vektor benutzen zu müssen.
Wie oben geschrieben, gilt dies bei der Erweiterung von 16 Bit Timern auf 32 Bit - sofern notwendig.
@TO:
Ich habe noch einen Vorschlag für Dich, die Zähler in einen externen ATtinyXX2 zu packen: http://mino-elektronik.de/mt12_iic/mt12_iic.htm#qcnt_tiny202
Anstelle der Eingänge PHA und PHB müßte man das Programm auf STEP/DIR anpassen. Vielleicht mache ich das noch selber.
Wir wissen nicht, wieviele ns zwischen der Änderung von DIR und dem
nächsten STEP minimal vergehen.
Wir wissen, dass es sich um eine CNC-Fräße handelt. Die beschleunigt und bremst ab. Bei einer Richtungsumkehr wird normal einiges berechnet, so dass nicht beide Pulse gleichzeitig kommen.
Die ISR muß daher noch nachsehen, was zu tun ist und hoffen, daß sich
zwischendurch nichts verändert hat.
Die Annahme, daß sich die Richtung nur eher selten ändert, ist mir zu
optimistisch.
Das Nachsehen bei einem Überlauf von 5x 16-Bit Timern ist keine Zauberei. Selbst bei den genannten 250kHz passiert das nur wenige Male in der Sekunde.
Ich habe mir den genannten Controller nicht genau angeschaut, viele bieten auch die Möglichkeit einen Timer als "Prescaler" zu nehmen. Vielleicht gibt es ja die Möglichkeit solch einen STM32 auszuwählen.
Und die Richtungsumkehr kommt definitiv bei einer CNC Fräse nicht oft vor, weil das physikalisch nicht geht.
Die Dir-Signale kommen natürlich an eigene Pins mit Interrupt und haben nichts mit den Countern zu tun, außer eben dass sie im Interrupt das Register eines Counter ändert um dle Zählrichtung umzudrehen.
Da bis 250kHz angegeben ist gehe ich außerdem von einem sehr hohen Mikrostepping aus. Da macht ein verschluckter Step nichts aus, da die Auflösung dann deutlich höher ist als die Genauigkeit der Fräse. Da sie außerdem genau so oft in die eine wie die andere Richtung fährt, gleichen sie sich aus (sofern das überhaupt vorkommt)
sondern um einen verschluckten Überlauf eines Timers.
Wie gesagt, der Überlauf selbst kommt maximal 10x pro Sekunde vor, keine Ahnung wie die sich da verschlucken sollen. Der Timer setzt auch ohne Interrupt die Flag, dann prüft man halt in jedem Interrupt alle Flags ab.
Wie gesagt, der Überlauf selbst kommt maximal 10x pro Sekunde vor
Das ist leider nicht so.
Theoretisch kann man auch im Überlaufbereich nur einige Takte hin und her pendeln, z.B. Abzeilen von sehr kleinen Flächen beim Fräsen, dan kommt der Überlauf hunderte wenn nicht gar tausende male pro Sekunde.
Dann rück mal raus mit den Mikroschritten, der maximalen Beschleunigung und dem Ruck, wenn du die Achse mit 1KHz vorwärts und rückwärts fahren lässt.
Idealerweise gleich noch sagen wieviel Mikrometer ein Schritt entspricht.
Du sagst, du machst es aktuell mit Interrupts. Meine Variante ist deutlich besser (wenn es vorher geklappt hat reicht es definitiv) und lässt 98% der CPU Teit übrig für andere Aufgaben.
Kurzes Rechenbeispiel:
Schrittmotor maximale Drehzahl bevor das Drehmoment komplett abgefallen ist: 10U/s. Bei 200 Pulse pro Umdrehung sind das maximal 2000 Vollschritte pro Sekunde. Für 250kHz bräuchte man 128 Mikroschritte.
Bei einer maximalen Geschwindigkeit der Fräse von 1500mm/min wäre ein Vollschritt also 25mm/s bei 2000 Vollschritten pro Sekunde bei etwa 12,5um.
Ein verpasster Mikroschritt ist also irgendwo bei 100nm Fehler. Aus Erfahrung kann ich dir sagen, dass thermischer Drift, ungenaue Gewindesteigung und Spiel deutlich mehr Fehler verursachen. Ganz zu Schweigen davon, dass ein Schrittmotor solch eine Auflösung mechanisch nicht her gibt.
Von daher kann deine Fehlerbetrachtung maximal von akademischer Natur sein.
Derzeitiger Stand:
STEP/DIR zu A/B quadrature Wandler mittels AVRSTM32:
TIM2 u. TIM5 lesen quadrature direkt in 32bit counter register
TIM1,TIM3 und TIM4 werden over-/underrun der 16bit counter mit
interrupts in 32 bit Werte weitergegeben
Von daher kann deine Fehlerbetrachtung maximal von akademischer Natur
sein.
Ich kenne die Thematik. Ich baue seit Jahrzehnten die verschiedensten Hobby-CNC Maschinen. Nun geht es aber um ganz andere Sachen. "TCPM" 5-Achs Maschinenkinematk Berechnung in Echtzeit. D.h. werden hier Takte verschluckt werden auch diese Berechnungen falsch sein. Nicht nur so wie bei einer normalen 3-achs Kinematik dass eine Achse ein paar Steps daneben steht. Daher muss das Lesen der Signale zu 1000% sicher funktionieren bevor ich mich den nächsten Themen dieses Projektes widme.
Erste tests heute Nacht sehen sehr gut aus. Alle 5 Achsen mal ca. 20min auf "Vollgas" ein 5x CNC Programm laufen lassen. Zumindest 4 Achswerte konnte ich am LCD Display kontrollieren , TIM2,3,4,5 passten exakt.
Stresstest Programm im over-/underrun Bereich der 3 16bit Timer werde ich ev. heute abend machen.
Ja, das Problem, warum es keine Hardware Schnittstelle gibt, die automatisch Step und Dir Signale einliest ist, dass es ja nicht wie A/B ein Sensorsignal ist, sondern ein Steuersignal, was vom Prinzip her irgendwo bekannt sein muss. Wenn man das einlesen muss ist beim System etwas nicht richtig.
Es gibt verschiedene Varianten:
STM32 und Timer im Counter Mode, wie ich das geschrieben habe.
Umwandlung in A/B Signal. Hier gibt es bestimmt eine analoge Schaltung (A und B durch Flip Flops erzeugt (eins bei fallender das andere auf steigende Flanke). Das Dir Signal investiert ein Ausgabgssignal eines Flip Flops.
Ja, das Problem, warum es keine Hardware Schnittstelle gibt, die
automatisch Step und Dir Signale einliest ist, dass es ja nicht wie A/B
ein Sensorsignal ist, sondern ein Steuersignal, was vom Prinzip her
irgendwo bekannt sein muss. Wenn man das einlesen muss ist beim System
etwas nicht richtig.
Ist aber eben bei Hobby-CNC PC-Steuerungen seit je her standard
(Mach3, mach4, UCCNC, Benazan, .....)
Wandlung step/dir --> A/B sehe ich als erledigt , geht im AVR zuverlässig.
over/underrun der 3 16bit counter muss ich noch weiter testen.
Ich muß mich korrigieren: Laut STM32F411-Datenblatt sind es vier Timer (TIM2 bis TIM5), laut Reference Manual fünf Timer (TIM1 bis TIM5), die das können.
vorerst einmal DANKE für die vielen Tipps die ich in diesem Thread erhalten habe.
Ich habe in letzter Zeit nun einige Varianten durch probiert, d.h. Stresstests mit verschiedenen G-Codes über mehrere Stunden Laufzeit bei max. speed. (380kHz an allen 5 Achsen)
Dabei wurde besonders darauf geachtet dass die benötigten Interrupts f.
16bit Timer- Über/Unterlauf und Richtungsumkehr alle gemeinsam angefordert wurden.
Hier meine Varianten u. Ergebnisse:
A:
5 externe AVR's mit dem Code von Falk.
stp/dir->AB quadrature -> STM32
Ergebnis: 1A; 0 Fehler an allen 5 Achsen über mehrere Stunden
B:
5 externe AVR's mit meinem Code (Int0).
stp/dir->AB quadrature -> STM32
Ergebnis: 1A; 0 Fehler an allen 5 Achsen über mehrere Stunden
C:
STEP Signale an STM32 Timer1-5
DIR Signale an Eingangpins mit Interrupts
Ergebnis: 2-5 Steps Fehler an verschiedenen Achsen über mehrere Stunden
Also stand fest , Variante A od. B wird verwendet.
Aber irgendwie ließ mich der Gedanke einfach nicht los
dass es direkt am STM32 auch laufen muss.
Also nochmal an den Tmer Registern stundenlang rumgebastelt bis ich eine Lösung hatte.
Hier die Timer Register Einstellung:
1
RCC_APB1ENR.TIM2EN = 1
2
TIM2_CR1.EN = 0
3
TIM2_CCMR1_Input.CC1S0 = 1
4
TIM2_CCMR1_Input.CC1S1 = 0
5
TIM2_CCMR1_Input.CC2S0 = 1
6
TIM2_CCMR1_Input.CC2S1 = 0
7
TIM2_CCER.CC1P = 1
8
TIM2_CCER.CC1NP= 1
9
TIM2_SMCR.SMS0 = 1
10
TIM2_SMCR.SMS1 = 0
11
TIM2_SMCR.SMS2 = 0
12
TIM2_ARR = 4294967295
13
TIM2_PSC = 0
14
TIM2_CR1.EN = 1
Damit lässt sich ein STP/DIR Signal an den quadrature Eingängen einwandfrei lesen.
Der Timerwert muss noch durch 2 dividiert werden , aber damit kann ich leben.
Tests ,nur steigende od. fallende Flanke am STP Eingang zu verwenden,
funktionieren nicht.
Auch "TIMx_PSC = 1" funktioniert nicht da dieser Wert erst beim ersten Richtungswechsel , dh. Flankenwechsel am DIR Eingang gelesen wird.
Falls mal jemand in der Zukunft ein ähnliches Problem hat, diesen Faden findet und warum auch immer die Lösung von Gerhard nicht verwenden kann oder will: Ich stieß beim Stöbern bei Digi-Key auf den LS7184N, der konvertiert von A/B nach STEP/DIR. Kostet deutlich mehr als ein ATtiny o.ä. und ist ein Marktplatzangebot (wohl direkt vom Hersteller), dafür muß er nicht programmiert werden.
Ich weiß, ich bin eigentlich zu spät, aber würde nicht ein einfacher D-Flip-Flop pro Kanal reichen? Das wären dann 2,5 mal 74HC74 statt 5 AVRs.
Da der Encoder-Modus immer beide Flanken zählt, schaltet man den Flip-Flop als 1-Bit Prescaler für STEP (^Q auf D). Der 3-fach XOR ist in jedem der 5 Timer ja schon drin. Der muß alle 3 Signale (DIR, STEP und STEP/2) verbinden, und schon hat man den anderen Bit vom Gray-Code:
1
DIR S S/2 XOR
2
0 0 0 0
3
0 1 1 0
4
0 0 1 1
5
0 1 0 1
6
0 0 0 0
7
8
1 0 0 1
9
1 1 1 1
10
1 0 1 0
11
1 1 0 0
12
1 0 0 1
Mit TI1S=1 liegt der XOR-Ausgang an TI1. Jetzt muß STEP/2 noch auf CH2/TI2 liegen und mit SMS=001 nur TI2-Flanken gezählt werden.
Zur Sicherheit sollten die Signale gefiltert werden (IC1F und IC2F). Vor allem TI1, weil STEP/2 immer ganz kurz nach STEP schaltet (Verzögerung des Flip-Flops), und am XOR-Ausgang deswegen Gliches auftreten können. Zu jeder anderen Zeit dürfen DIR und TI1 feiern, was sie wollen. Daher sind diese Fälle auch nicht in der Tabelle oben drin.
Alle Angaben ohne Gewähr. Ich bin auf diesen Thread nur gerade zufällig gestoßen und habe nichts davon ausprobiert.
PS: TIM9 im 1-bit PWM Modus kann das 5. Flip-Flop ersetzen, womit nur noch 2 externe Chips nötig sind. Keine Ahnung, ob das alles gleichzeitig auf Pins zu mappen ist. Hauptsache, die philosophische Frage nach einer rein internen Lösung ist damit mit "ja" beantwortet ;)
Die ISR muß daher noch nachsehen, was zu tun ist und hoffen, daß sich
zwischendurch nichts verändert hat.
"hoffen" ist in der Software immer ein schlechtes Konzept. Das führt zu seltenen, scheinbar unerklärlichen Fehlern, die entsprechend übel zu debuggen sind.
Im Fall eines Dir-Interrupts müsstest du einen Blick in die Zeitspezifikationen deiner Geber werfen. Vermutlich ist die Reaktion auf den Interrupt so langsam, dass dein Hardwarezähler noch einen Puls mit der alten, falschen Richtung zählt, bevor die Interruptroutine so weit ist, dass sie die Richtung umschalten kann. Da müsste der Zählerstand dann korrigiert werden.
Zur Kontrolle ist es sicher gut, in der ISR das Dir-Signal noch einmal einzulesen und zu prüfen. Da kommt es auch drauf an, wie sauber die Signale von deinen Gebern kommen.