Hallo Leute, 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. Schönes Wochenende, Gerhard
Für den Fall, daß die Timer nicht passend konfiguriert werden können, hier eine Hardwarelösung. Beitrag "Re: pulse direction signal zu encoder a b?"
Hallo Falk, 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. Gruss Gerhard
Gerhard H. schrieb: > Gibt es eine Möglichkeit die Timer Register so zu konfigurieren dass sie > auch mit STEP/DIR Signalen so problemlos umgehen können ? Nein. Gerhard H. schrieb: > 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.
:
Bearbeitet durch User
Mi N. schrieb: > 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..) BG Gerhard
Gerhard H. schrieb: > 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. Zeig mal einen Link auf ein Datenblatt.
Gerhard H. schrieb: > 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 ;-)
Hi, hier die links Reference manual https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwjph_XQ3qT_AhXWv4sKHfncAGwQFnoECBsQAQ&url=https%3A%2F%2Fwww.st.com%2Fresource%2Fen%2Freference_manual%2Fdm00119316-stm32f411xc-e-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf&usg=AOvVaw0C62LHdBLeEzv0gu85BWOe Timer overview https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwipz5qB36T_AhVEl4sKHQI7CesQFnoECBMQAQ&url=https%3A%2F%2Fwww.st.com%2Fresource%2Fen%2Fapplication_note%2Fan4013-stm32-crossseries-timer-overview-stmicroelectronics.pdf&usg=AOvVaw1fHpOR5H7BmAmFcePnHt9t
Mi N. schrieb: > Mit einem guten C-Compiler ginge das vielleicht auch schon. Es wäre > einen Versuch wert - aber nicht bei schönem Sonnenwetter ;-) Da war gerade eine Wolke am Himmel, siehe Anhang. Die war aber sehr klein, weshalb ein Test entfallen mußte ;-)
Falk B. schrieb: > 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.
Mi N. schrieb: > 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.
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.
Mi N. schrieb: >> 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.
:
Bearbeitet durch User
Beitrag #7426339 wurde vom Autor gelöscht.
Geht es nur ums Mitschreiben, oder sollen die Signale im STM32F411 erzeugt werden?
Mi N. schrieb: > 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. Falk B. schrieb: > Hier mal als ASM. Kann man kaum schneller machen. Danke, kann ich ev. gebrauchen. Walter T. schrieb: > 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.
Gerhard H. schrieb: > Der Debugger von MikroE sagt mir dass > er ca. 120 Takte braucht um in die ISR rein u. raus zu kommen. Das klingt viel, aber weniger als die Hälfte wird es wohl nicht. Sind da die 24 Takte, um die ISR zu starten und zu verlassen schon dabei? Sind alle Eingänge an einem Port, daß Du die Dekodierung direkt parallel mit allen Pins gleichzeitig in einem Datenwort machen kannst?
Walter T. schrieb: > 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.
Hallo, 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.
1 | $regfile = "m328pdef.dat" |
2 | $crystal = 16000000 '16Mhz Quarz |
3 | $hwstack = 100 : $swstack = 200 : $framesize = 200 |
4 | |
5 | '----------------------------------------------------------- |
6 | ' |
7 | ' ___________ |
8 | ' C-out A TXD D1 -| |- V_IN |
9 | ' C-out B RXD D0 -| o o o |- GND |
10 | ' Reset C6 -| - o + |- C6 Reset |
11 | ' GND -| |- 5V out |
12 | ' X-Step INT0 D2 -| Arduino |- |
13 | ' Y-Step INT1 D3 -| |- |
14 | ' Z-Step T0 D4 -| N |- C5 Z-out B |
15 | ' A-Step T1 D5 -| A |- C4 Z-out A |
16 | ' C-Dir D6 -| N |- C3 Y-out B |
17 | ' C-Step D7 -| O |- C2 Y-out A |
18 | ' X-Dir B0 -| |- C1 X-out B |
19 | ' Y-Dir B1 -| |- C0 X-out A |
20 | ' Z-Dir B2 -| ___ |- |
21 | ' A-Dir B3 -| | | |- 3v3 out |
22 | ' A-out A B4 -| | | |- B5 A-out B onboardLED |
23 | ' ----------- |
24 | ' |
25 | '------------------------------------------------------------------------------- |
26 | |
27 | Config Portb = &B1111_1111 ' alle Pins output |
28 | Config Portc = &B0011_0000 ' 4+5 output , Rest input |
29 | Config Portd = &B0000_0011 ' 0+1 output , Rest input |
30 | |
31 | '--- Config Interrupts ------------------------------------- |
32 | |
33 | Config Int0 = Falling |
34 | On Int0 X_step Nosave |
35 | Enable Int0 |
36 | |
37 | Config Int1 = Falling |
38 | On Int1 Y_step Nosave |
39 | Enable Int1 |
40 | |
41 | Config Timer0 = Counter , Edge = Falling |
42 | On Timer0 Z_step Nosave |
43 | Enable Timer0 |
44 | |
45 | Config Timer1 = Counter , Edge = Falling |
46 | On Timer1 A_step Nosave |
47 | Enable Timer1 |
48 | |
49 | |
50 | Config Aci = On , Compare = On , Trigger = Falling |
51 | Acsr.acbg = 1 ' Int.Ref |
52 | On Aci C_step Nosave |
53 | Enable Aci |
54 | |
55 | Enable Interrupts |
56 | |
57 | Portb = 0 |
58 | Timer0 = 255 |
59 | Timer1 = 65535 |
60 | |
61 | $asm |
62 | ldi r28,&B00000001 '1 |
63 | ldi r29,&B00000100 '4 |
64 | ldi r30,&B00010000 '16 |
65 | ldi r31,&B01000000 '64 |
66 | SER R26 '256 |
67 | $end Asm |
68 | |
69 | ' --- Do - Loop ------------------------------------------ |
70 | Do |
71 | Loop |
72 | End |
73 | |
74 | ' --- INTERRUPTS ------------------------------------------ |
75 | |
76 | X_step: |
77 | $asm |
78 | in r8,SREG |
79 | sbic pinB , 0 'Dir Pin |
80 | Subi R16 , 2 '-2 |
81 | add r16,r28 '+1 |
82 | mov r17,r16 'copy |
83 | ANDI r17, &B00000011 'bit 0 und 1 isolieren |
84 | sbrc r17,1 |
85 | eor r17,r28 'unteres Bit umdrehen wenn oberes Bit 1 |
86 | in r27 , portC |
87 | ANDI r27, &B11111100 'output Register isolieren |
88 | add r27 , r17 'bit 0 u 1 out |
89 | Out Portc , R27 |
90 | Out Sreg , R8 |
91 | $end Asm |
92 | Return |
93 | |
94 | Y_step: |
95 | $asm |
96 | in r8,SREG |
97 | sbic pinB , 1 'Dir Pin |
98 | Subi R18 , 8 '-8 |
99 | add r18,r29 '+4 |
100 | mov r19,r18 'copy |
101 | ANDI r19, &B00001100 'bit 2 und 3 isolieren |
102 | sbrc r19,3 |
103 | eor r19,r29 'unteres Bit umdrehen wenn oberes Bit 1 |
104 | in r27 , portC |
105 | ANDI r27, &B11110011 'output Register isolieren |
106 | add r27 , r19 'bit 2 u 3 out |
107 | Out Portc , R27 |
108 | Out Sreg , R8 |
109 | $end Asm |
110 | Return |
111 | |
112 | Z_step: |
113 | $asm |
114 | in r8,SREG |
115 | Out Tcnt0 , R26 'timer auf 255 setzen |
116 | sbic pinB , 2 'Dir Pin |
117 | Subi R20 , 32 '-32 |
118 | add r20,r30 '+16 |
119 | mov r21,r20 'copy |
120 | ANDI r21, &B00110000 'bit 4 und 5 isolieren |
121 | sbrc r21,5 |
122 | eor r21,r30 'unteres Bit umdrehen wenn oberes Bit 1 |
123 | in r27 , portC |
124 | ANDI r27, &B11001111 'output Register isolieren |
125 | add r27 , r21 'bit 4 u 5 out |
126 | Out Portc , R27 |
127 | Out Sreg , R8 |
128 | $end Asm |
129 | Return |
130 | |
131 | A_step: |
132 | $asm |
133 | in r8,SREG |
134 | Out Tcnt1l , R26 'timerL auf 255 setzen |
135 | Out Tcnt1l , R26 'timerH auf 255 setzen |
136 | sbic pinB , 3 'Dir Pin |
137 | Subi R22 , 32 '-32 |
138 | add r22,r30 '+16 |
139 | mov r23,r22 'copy |
140 | ANDI r23, &B00110000 'bit 4 und 5 isolieren |
141 | sbrc r23,5 |
142 | eor r23,r30 'unteres Bit umdrehen wenn oberes Bit 1 |
143 | in r27 , portB |
144 | ANDI r27, &B11001111 'output Register isolieren |
145 | add r27 , r23 'bit 4 u 5 out |
146 | Out Portb , R27 |
147 | Out Sreg , R8 |
148 | $end Asm |
149 | Return |
150 | |
151 | C_step: |
152 | $asm |
153 | in r8,SREG |
154 | sbic pinD , 6 'Dir Pin |
155 | Subi R24 , 2 '-2 |
156 | add r24,r28 '+1 |
157 | mov r25,r24 'copy |
158 | ANDI r25, &B00000011 'bit 0 und 1 isolieren |
159 | sbrc r25,1 |
160 | eor r25,r28 'unteres Bit umdrehen wenn oberes Bit 1 |
161 | in r27 , portD |
162 | ANDI r27, &B11111100 'output Register isolieren |
163 | add r27 , r25 'bit 0 u 1 out |
164 | Out Portd , R27 |
165 | Out Sreg , R8 |
166 | $end Asm |
167 | Return |
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%.
Wenn man Interesse hat, kann man das auch in einen CPLD packen, die gibt es ziemlich billig auf Ebay. Hier incl. Programmieradapter für unter 15 Euro! https://www.ebay.de/itm/232684120955 Oder der hier, allerdings braucht man dann noch den Programmieradapter für XILINX. https://www.ebay.de/itm/385453238900 https://www.ebay.de/itm/272374665838 Hier der XILINX Adapter, natürlich etwas teuer für die Einzelanwendung. https://www.ebay.de/itm/272600102573 Hier die Billigversion, aber wer hat schon noch einen echten Parallelport am Computer? https://www.ebay.de/itm/202022683374 Wenn du magst, kann ich dir so einen CPLD von XILINX programmieren, ich hab das Kabel und Know How hier. Altera kann ich nicht, hab kein Kabel dafür.
Gerhard H. schrieb: > Hallo, > > 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.
Gerhard H. schrieb: > 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. Gerhard H. schrieb: >> 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.
Gerald M. schrieb: > 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.
Gerald M. schrieb: > Bei einem "dir-Interrupt" entsprechend die Richtung des Counters > einstellen. Fertig. Werde ich auch mal probieren Zino schrieb: > 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.
Gerhard H. schrieb: > Leider habe ich dazu auch keine Info , bzw. nicht die Mittel dies zu > messen. > Der step Impuls ist 12 ns breit. WIRKLICH? Kann ich nicht ganz glauben. Und das willst du per SOFTWARE dekodieren! Viel Glück!
Gerhard H. schrieb: > Der step Impuls ist 12 ns breit. ohje FEHLER !!! , Impulsbreite ist 1,2µs also 1200ns
:
Bearbeitet durch User
Gerald M. schrieb: > 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.
Zino schrieb: > 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. Mi N. schrieb: > 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. Mi N. schrieb: > Timer 2 - 5 haben nur einen ISR-Vektor. 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)
Gerald M. schrieb: > Da macht ein verschluckter Step nichts aus, da die > Auflösung dann deutlich höher ist als die Genauigkeit der Fräse. Es geht mir nicht um einen verschluckten Schritt, sondern um einen verschluckten Überlauf eines Timers. Aber schön, wenn alles so einfach ist.
Mi N. schrieb: > 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.
:
Bearbeitet durch User
Gerald M. schrieb: > 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. Gerald M. schrieb: > Da macht ein verschluckter Step nichts aus Doch , auch ein verlorender Takt ist zuviel. Da ich die Genauen Werte in trigonometrischen Funktionen weiter verrechne muss da ALLES stimmen.
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.
Gerald M. schrieb: > 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. für die derzeitigen Tests habe ich 1µm für einen Schritt eingestellt. 1000 Schritte = 1mm 250000 Schritte/s / 1000 = 250mm/s =15m/min Schub Gerald M. schrieb: > Du sagst, du machst es aktuell mit Interrupts Derzeitiger Stand: STEP/DIR zu A/B quadrature Wandler mittels AVR STM32: 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 Gerald M. schrieb: > 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.
:
Bearbeitet durch User
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. FPGA macht das problemlos 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.
Gerald M. schrieb: > 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.
Der STM32F411 kann quadrature encoder input nur für vier Timer, der TO braucht das für fünfe.
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.
Hallo, 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. BG Gerhard
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.
Zino schrieb: ... > konvertiert von A/B nach STEP/DIR. Der Thread ging aber um STEP/DIR eingangssignale...
Wenn man nicht programmieren will, geht auch der Vorschlag: Beitrag "Re: pulse direction signal zu encoder a b?"
Hallo Gerald, der Tip wurde am Thread Anfang schon von Falk gegeben BG Gerhard
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 ;)
Mi N. schrieb: > 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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.