Hi Leutz, hatte ja vor kurzem angefangen, meine ersten Erfahrungen mit der Schrittmotoransteuerung + L293D zu machen. Hatte schon ein fertiges Programm auf dem AVR-Testboard geschrieben, welches ja mit dem externen Quarz auf 3,68MHz lief. Nun sollte der ATmega8 in eine Schaltung eingesetzt werden, welche natürlich ohne diesen Quarz läuft. Habe also die Fusebits gesetzt und den ATmega8 auf 8Mhz eingestellt. Nun funktioniert zwar die Ansteuerung des Schrittmotors noch (mit Anpassung der Ansteuerungszeiten), nur leider die IF-Schleife (diese zählt 132 Schritte), die den Schrittmotor an einem bestimmten Punkt anhalten soll, nicht mehr. Es ist als würde es diese Schleife überhaupt nicht mehr geben. Ist der ATmega8 ohne externen Quarz so schnell überfordert? Was kann ich vielleicht noch tun, damit ich die schöne fertige Platine nicht in die Tonne treten kann? Beste Grüße. Daniel
Daniel Lo schrieb: > IF-Schleife Siehe: http://www.if-schleife.de/ Div8 Fusebit möglicherweise übersehen? Ansonsten kann man zu deiner "Schleife" ohne Code nichts sagen...
Das Fusebit Div8 wird mir beim ATmega8 gar nicht angeboten, habe ich auch schon nach gesucht. Schalte ich um auf z.B. den ATTiny13, ist dieses Bit wieder sichtbar. Hier mal ein Auszug des Quellcodes... Die Variablen sind alle global deklariert worden und wie schon gesagt, MIT dem Quarz lief das Programm einwandfrei ab. if (w<132) { PORTB=0b00000101; //1.Schritt for (a=0;(a<130);a++) { } PORTB=0b00000001; //1.Halbschritt for (a2=0;(a2<130);a2++) { } PORTB=0b00001001; //2.Schritt for (b=0;(b<130);b++) { } PORTB=0b0001000; //2.Halbschritt for (b2=0;(b2<130);b2++) { } PORTB=0b00001010; //3.Schritt for (c=0;(c<130);c++) { } PORTB=0b00000010; //3.Halbschritt for (c2=0;(c2<130);c2++) { } PORTB=0b00000110; //4.Schritt for (d=0;(d<130);d++) { } PORTB=0b00000100; //4.Halbschritt for (d2=0;(d2<130);d2++) { } w++; }
Vermutlich ist das Timing falsch! Mess mal die Zeiten am Port (mit Oszi) und vergleiche sie mit den Zeiten bei der 3,68MHz-Quarz-Version. Dann kannst Du auf den tatsächlichen Takt "ohne diesen Quarz" schließen und die Warteschleifen (oder den Takt) entsprechend anpassen. Gruß Dietrich
Das Problem sind ja anscheinend nicht einmal die Zeiten... Ich habe probeweise mal den Wert der IF-Abfrage auf <1 heruntergesetzt. Der Motor dreht durch bis in den mechanischen Anschlag und stoppt gar nicht mehr. Eben so als gäbe es diese IF-Abfrage überhaupt nicht. Setze ich hingegen die IF-Abfrage auf >1, so tut sich gar nichts (was ja auch in diesem Falle richtig wäre). Es sieht für mich so aus als würde die Anweisung w++; überhaupt nicht mehr richtig bearbeitet...
Hmm, meine Glaskugel sagt mir du hast R12 falsch herum eingelötet und bei C3 Kapazitäts und Spannungswert vertauscht. Aber diese modernen Murmeln haben inzwischen so hohe Auflösungen bei kleinem Durchmesser. Vieleicht sehe ich das ohne meine Brille nicht so richtig? Ach ja die Variable k muss volatile sein.
Kannst du das Programm nicht in den Simulator packen und dort mal Schritt für Schritt abarbeiten lassen? Ich hatte ein sehr ähnliches Problem, es wurde verzweigt, obwohl die abgefragte Variable den Wert gar nicht hatte. die Abfrage war: cpi r16,1 breq Label1 Variable r16 war 0, aber es wurde trotzdem nach Label 1 gesprungen ... Das Problem war eine Interrupt-Routine, die auch mal zwischen dem CPI-Befehl und dem BREQ-Befehl eigeschoben wurde und die Statusregister verändert hatte ...
Daniel Lo schrieb: > for (d2=0;(d2<130);d2++) > { > } wurde möglicherweise "wegoptimiet"... steht da wirklich nichts drin? Kein Delay etc? Falls dem so ist "flackert" wömöglich die Pins einmal kurz durch und der L293 denkt sich seinen teil...
In der For-Schleife steht nichts drin, da dort ja nur Zeit verbraten werden soll. Der Ausdruck ist also quasi das Delay. Die Ansteuerung selbst ist sowohl mit als auch ohne Quarz (mit anderen Werten in den jeweiligen FOR-Schleifen) möglich, nur die IF-Abfrage funktioniert nicht mehr!
Daniel Lo schrieb: > In der For-Schleife steht nichts drin, da dort ja nur Zeit verbraten > werden soll. Der Ausdruck ist also quasi das Delay. Und das ist, mit Verlaub gesagt, einfach nur Scheisse. Wenn du tatsächlich einfach nur Zeit verbraten willst, gibt es die Funktionen _delay_ms() bzw. _delay_us() F_CPU eintragen, die gewünschte Zeit beim Aufruf angeben, sicher stellen, dass die Compiler-Optimierungen an sind und die Zeiten stimmen. Egal bei welcher Taktfrequenz. >>> AVR-GCC-Tutorial <<<
1 | #define F_CPU 8000000UL
|
2 | |
3 | #include <util/delay.h> |
4 | |
5 | #define STEP_DELAY 10
|
6 | |
7 | ....
|
8 | |
9 | while( 1 ) { |
10 | |
11 | ...
|
12 | |
13 | if (w<132) |
14 | {
|
15 | PORTB = 0b00000101; //1.Schritt |
16 | _delay_ms( STEP_DELAY ); |
17 | PORTB = 0b00000001; //1.Halbschritt |
18 | _delay_ms( STEP_DELAY ); |
19 | PORTB = 0b00001001; //2.Schritt |
20 | _delay_ms( STEP_DELAY ); |
21 | PORTB = 0b0001000; //2.Halbschritt |
22 | _delay_ms( STEP_DELAY ); |
23 | PORTB = 0b00001010; //3.Schritt |
24 | _delay_ms( STEP_DELAY ); |
25 | PORTB = 0b00000010; //3.Halbschritt |
26 | _delay_ms( STEP_DELAY ); |
27 | PORTB = 0b00000110; //4.Schritt |
28 | _delay_ms( STEP_DELAY ); |
29 | PORTB = 0b00000100; //4.Halbschritt |
30 | |
31 | w++; |
32 | }
|
33 | ....
|
34 | }
|
Kannst du ausschließen, dass der Compiler diese Schleifen nicht auslässt, da er erkennt, das darin nichts passiert? Toggel in den Schleifen doch einmal einen Pin, falls du noch einen unbenutzen frei hast... Alternativ ersetze die For-Schleifen doch mal durch die delay()... Ansonsten können wir schlecht erkennen, warum er ggf. die IF auslässt ohne kompletten Code... w ist zu Beginn 0 oder 1, denke ich?
> Das Problem war eine Interrupt-Routine, die auch mal zwischen dem > CPI-Befehl und dem BREQ-Befehl eigeschoben wurde und die > Statusregister verändert hatte ... Tjo, deswegen sollten Interruptroutinen IMMER das Statusregister mit den Flags sichern. Schade, daß der AVR dafür keinen einzelnen Befehl hat wie der x86 (der kennt PUSHF/POPF).
Daniel Lo: Hast Du die Optimierung des Compilers schon mal abgeschaltet? Stryker hat schon mehrmals darauf hingewiesen! Gruß Dietrich
So, hab's jetzt einfach mal mit der Delay-Variante probiert. Das Ergebnis ist leider dasselbe wie bei der FOR-Variante. Die Variable w habe ich ganz zu anfangs einmalig auf den Startwert 0 gesetzt. Gibt es eine Möglichkeit, die Compileroptimierung abzuschalten beim MyAVR-Workpad Plus?
Daniel Lo schrieb: > Gibt es > eine Möglichkeit, die Compileroptimierung abzuschalten beim > MyAVR-Workpad Plus? Siehe myavr.info/myforum/viewtopic.php?p=5048 Wie aber nun die Parameter sind hängt von deinem verwendeten Compiler ab - hier ist Google dein Freund. Aber falls das delay das tut, was es sollte hilft dir das hier leider nicht. Teste das Delay doch am besten einmal mit einer LED die nach 1Sek. angeht. Ich bin mir ziemlich sicher, dass es am Timing in Kombination mit dem "durchflitzen" der If-Anweisung liegt. Das wird schon noch ;-)
Daniel Lo schrieb: > So, hab's jetzt einfach mal mit der Delay-Variante probiert. Das > Ergebnis ist leider dasselbe wie bei der FOR-Variante. Die Variable w > habe ich ganz zu anfangs einmalig auf den Startwert 0 gesetzt. Zeig deinen Code. Beschreib ihn nicht. > Gibt es > eine Möglichkeit, die Compileroptimierung abzuschalten beim > MyAVR-Workpad Plus? Das ist kontraproduktiv. Wenn du richtig programmierst, brauchst du die Optimierung nicht abzuschalten. Du willst die Optimierung behalten! Also musst du richtig programmieren.
So... nach Stunden über Stunden der Sucherei hab ich nun einfach die Fusebits mit MyAVR-Progtool nochmals geschrieben anstatt mit MyAVR-Workpad Plus. Und siehe da... es läuft!!! (ich könnt kotzen...) Habe ihn jetzt auf 2 MHz zum Test laufen lassen und nun funktionert er auch in der Schaltung, wenn auch langsamer. Werde jetzt nochmal die Taktrate umstellen und die Zeiten anpassen. Mal ne Frage in die Runde. Sind Fehler bezüglich der Fusebits in Verbindung mit dem MyAVR Workpad Plus bekannt? Habe die Version 1.5 (Build 3304). Danke für die vielen Tipps! Daniel
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.