Hallo,
Ich will drei Schrittmotoren ueber den Druckerausgang meines Computers
steuern.
Das Signal aus dem Druckerausgang kommt auch am Atmega16 an, und loest
dort auch das Interrupt aus (Die LED an PB4 blinkt). Allerdings wird
"xstepin" anscheinend nicht gesetzt , da die IF Anweisung unter "//X
Step Direction 0" anscheinend nicht ausgeloest wird (Die LED an PC4
blinkt nicht).
Reicht es nicht das "xstepin" global als Volatile int deklariert ist?
Tut mit leid das ich euch einfach den ganzen Code vor die Fuesse werfe,
aber so kann es nicht passieren das der Fehler vielleicht doch wo anders
ist ;)
Falls ihr allerdings Fehler bei Y und Z findet koennt ihr diese
ersteinmal ignorieren. Im Moment beschraenke ich mich nur auf X um dort
den Fehler zu finden.
Vielen Dank schonmal fuer die Hilfe ;)
Ich habe auch schon Versucht die komplette Ansteuerung de Motors in das
Interrupt zu schreiben, auch wenn man das vielleicht nicht unbedingt
machen sollte.
Aber das hat auch nicht funktioniert.
>Das Problem muss irgendwo in diesem Bereich liegen:>Ich hab es leider immernoch nicht gefunden.
Code weiter reduzieren bis das Problem nicht mehr auftritt.
Hi,
Ich habe das Problem glaube ich gefunden, weiss aber nicht wie ich es
beseitigen kann.
Obwohl xstepin global ist, wird es in der main Funktion nicht als "1"
erkannt.
Allerdings bin ich mir sicher das das Interrupt ausgeloest wird und
xstepin=1 gesetzt wird.
Woran liegt das?
Hi,
Das Thema beschaeftigt mich immernoch xD
Und deshalb bin ich auf diesen Artikel gestossen:
Beitrag "WINAVR, Optimierung, Globale Variable, Volatile"
Verstehe ich das richtig das ich um auf die Variable "xstepin"
ausserhalb des Interrupts zuzugreifen die Interrupts deaktivieren muss?
Mfg und Danke ;)
@M. G.
Hab ich was an den AUgen, oder hast du in deinem main() tatsächlich
keine while-Hauptschleife.
PS: Deine { } Klammersetzung ist das unübersichtlichste, was ich in den
letzten 10 Jahren gesehen habe. Damit würde ich auch Unmengen von
logischen Fehlern machen.
Der Code würde von einer Restrukturierung und Aufteilung in einzelne
Funktionen nur profitieren. So wie er jetzt ist, ist er einfach nur
eines: eine lange Wurscht, bei der man nicht sieht, wie die Dinge
zusammengehören bzw. voneinander abhängen.
Wo sind deine Behandlungsfunktionen für den INT1 und INT2?
Man gibt keine Interrupts frei, für die man keinen Handler hat!
Tut man es trotzdem und tritt ein derartiger Interrupt auf, dann löst
das einen Prozessorreset aus.
M. G. schrieb:
Verstehe ich das richtig das ich um auf die Variable "xstepin"
> ausserhalb des Interrupts zuzugreifen die Interrupts deaktivieren muss?
Du solltest dich lieber fragen, warum diese Variable ein int (also 16
Bit) sein muss. Machst du sie als uint8_t dann hast du das Problem des
atomaren Zugriffs erst gar nicht.
Paul schrieb:> Ich hab das selbe Problem.
Wie kannst du dasselbe Problem haben?
Dein Programm sieht doch ganz anders aus!
Du magst vielleicht dieselben Symptome sehen, aber ob dafür dasselbe
Problem verantwortlich ist, ist eine ganz andere Geschichte.
@MG
Ich nehme Teile zurück. Ich hab mich nur auf die weiter unten geposteten
COdeteile konzentriert und nicht gesehen, dass du ganz am Anfang den
kmkopletten Code gepostet hast.
Allerdings trifft für den das Argument des Restrukturierens noch mehr zu
als, für den Ausschnitt.
Probier das mal aus
Ich musste das so gut es ging, auf einer Mega16 Hardware nachstellen.
Soweit funktioniert das auch alles.
Puls an PD2 schaltet den Motor 1 Schritt weiter. Der Pegel an PD5
bestimmt ob vorwärts oder rückwärts.
PS: Bist du sicher, dass deine Schrittmotoren mit Pulsen zufrieden sind?
Die haben ja dann gar kein Haltemoment mehr! Bei einem Schrittmotor
steht immer 1 (im Vollschrittbetrieb) Wicklung unter Strom. Ein Puls
alleine reicht da nicht. Ich hab das mal auf Dauerbestromung einer
Wicklung umgebaut.
Den _delay_ms in der ISR hab ich drinnen gelassen, damit du deine LED
flackern siehst. Die wird dann ja sowieso rausfallen und mit ihr der
_delay
Ich hab den Code noch ein bischen weiter aufgeräumt und angedeutet wie
er jetzt auf die restlichen beiden Achsen verallgemeinert.
Man könnte da noch mehr einsparen, und den Code noch kürzer formulieren.
Zb. in dem man die Motoranschlüsse in Arrays legt, dann braucht man
keine 3 gerennten Motor Funktionen mehr, sondern 1 Funktion erledigt das
für alle 3 Motoren. X, Y und Z Ansteuerung könnte man als Indizes in
Arrays auffassen usw. usw. Mit ein bischen guten Willen könnte man den
Code in Summe auf leicht unter 100 Zeilen bringen ohne dass er
unübersichtlich oder besonders trickreich wird.
Im Moment hab ich mich aber dagegen entschieden, damit du ihn noch
durchschauen kannst.
WOOW!
Danke das du dich so umfassend mit meinem Problem beschaeftigt hast !
Tut mir leid das das Programm so unleserlich und fehlerhaft geworden
ist.
Leider bin ich (noch) kein guter Programmierer.
Ich hab dein Programm mit einem Lauflicht und mit dem Schrittmotor
ausprobiert und es scheint zu funktionieren.
Allerdings liegt an PC0 nie Spannung an. Aber das muss jetzt ja an
meinem Controller liegen nehme ich an.
Vielein Dank nochmal!
M. G. schrieb:> Allerdings liegt an PC0 nie Spannung an. Aber das muss jetzt ja an> meinem Controller liegen nehme ich an.
Kann ich nicht bestätigen.
An meinem Mega16 läuft die leuchtende LED definitiv durch PC0-PC3 durch.
Und dreht auch brav um, wenn PD5 auf 1 liegt.
> Leider bin ich (noch) kein guter Programmierer.
Drum mach ich mir ja auch die Arbeit, damit du siehst wie man solche
Dinge machen kann, ohne dass alles gleich in eine if-else Orgie über 8
Seiten ausartet.
Bischen nachdenken, bischen Planung, ein paar Hilfsfunktionen und schon
dampft der Code in der Länge ordentlich ein. Was dann auch der Übersicht
zu gute kommt.
Hast du Y und Z schon aktiv?
Da hab ich einen COpy&Paste Fehler.
(ICh hätte doch die Variante mit einer Funktion für alle Motoren machen
sollen :-)
1
voidMotorZ(uint8_tNr)
2
{
3
MOTOR_X_PORT&=~((1<<PHASE_Z_0)|(1<<PHASE_Z_1)|
4
(1<<PHASE_Z_2)|(1<<PHASE_Z_3));
Muss natürlich MOTOR_Z_PORT heissen und nicht MOTOR_X_PORT
Überhaupt: Wenn du dann die Dinge für Y und Z einkommentierst, nicht
blind darauf vertrauen, dass ich alles richtig gemacht habe. Ich hab das
grossteils nur kopiert und X gegen Y resp. Z ausgetauscht. Da passiert
es schon mal, dass man was übersieht.
Ok, hab das Problem geloest. Es war tatsaechlich ein Hardwarefehler.
Jetzt klappt es wunderbar :)
Y und Z einzufuegen sollte wohl auch noch klappen ;)
Den code hab ich ja verstanden . Nur ihn selbst zu schreiben ist was
anderes.
Danke!