Hallo, ich habe eine Servosteuerung programmiert die nicht so recht laufen will. Um daher erstmal zu testen ob Servo etc. funktionieren, habe ich folgendes absolut simpele Programm geschrieben, welches NUR den Servo ungefähr in Mittelstellung setzen soll. Es ist so kurz dass ich es direkt hier posten kann: ========== DDRB |= (1 << PB1_SERVOOUT); // definiere PB1 als output // Aktiviere timer0 mit prescaler 64 (CS02,CS01,CS00) = (0,1,1) // Der Prozessortakt ist 8 MHz, entspricht 8000 Takten in 1ms. // Bei Prescaler 64 entspricht ein Zählerstand 125 genau 1ms TCCR0B |= (1 << CS01) | (1 << CS00); while(1){ PORTB |= (1 << PB1_SERVOOUT); // setze Bit PB1 TCNT0 = 0x00; while(TCNT0<(1504/8)); // warte ca. 1,5ms PORTB &= ~(1 << PB1_SERVOOUT); // lösche Bit PB1 // warte 10ms (ist ja nur ein Experiment!) TCNT0 = 0x00; while(TCNT0<(2000/8)); // wait 2ms TCNT0 = 0x00; while(TCNT0<(2000/8)); // wait 2ms TCNT0 = 0x00; while(TCNT0<(2000/8)); // wait 2ms TCNT0 = 0x00; while(TCNT0<(2000/8)); // wait 2ms TCNT0 = 0x00; while(TCNT0<(2000/8)); // wait 2ms } ========== Ich weiss dass das Programm alles andere als elegant ist. Aber das Ziel war einfach das ganze simpel und schnell zu machen. Es klappt trotzdem nicht. Der Servo wandert in schnellen kleinen Schritten zum vollen Ausschlag, und "tickt" dort dann stetig gegen den Anschlag. Ich habe alles x-mal gecheckt, das timing nachgerechnet (Taktfrequenz ist 8 MHz), die Schaltung überprüft, ... Leider habe ich kein Oszilloskop um das Signal zu checken. Habe ich in obigem Code einen doofen Fehler den ich nach 3 Stunden nun nicht mehr sehe? Hat jemand eine Idee woran es sonst liegen könnte? Bin schier am verzweifeln, ich muss Tomaten auf den Augen haben... Danke, groki
Vielleicht wird
1 | while(TCNT0<(2000/8)); // wait 2ms |
einfach wegoptimirt? Gruß, Lasse PS: Auch wenn der Code kurz ist, Code-Tags wären nett.
Ergänzung: Ziel-uC ist (noch) ein ATMEGA88, das Signal was ich erzeugen will ist: - 1,5ms Puls - 10ms Pause - 1,5ms Puls - 10ms Pause - ... und so weiter. Später soll es mal mit der PWM-Funktion des Timers laufen. So hatte ich es auch zuerst, aber da es nicht lief wollte ich diese Fehlerquelle zunächst "ausschalten"...!
Hallo Lasse, wie kann der Compiler das einfach wegoptimieren? Gibt es eine andere Möglichkeit eine Pause zu implementieren? Ist mein erstes Posting hier gewesen, hab die Code-tags nicht gesehen (ich sag's ja, Tomaten auf den Augen...). Werde ich nächstes Mal natürlich benutzen! Danke, groki
Er kann das einfach wegoptimieren, weil du nichts tust. Der Compiler erkennt, dass die Schleife für den Programmablauf sinnlos ist. Delay-Möglichkeiten gibt's im Tutorial: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29 Gruß Lasse
Danke, ich sehe es im Tutorial! Im Debugger lief's wie gewünscht, da wird's ja auch vorher compiliert. Und es wurde nicht wegoptimiert... Kann es sein dass es einen Unterschied macht ob ich debugge oder auf dem AVR laufen lasse? Ich probier's mal mit der _dela_ms() Funktion.
Hm, ich hab jetzt mal eine LED statt Servo angeschlossen, und folgenden einfachen Code:
1 | #define F_CPU 8000000UL // 8 MHz |
2 | |
3 | ... |
4 | |
5 | while(1){ |
6 | PORTB |= (1 << PB1_SERVOOUT); |
7 | _delay_ms(1000); |
8 | PORTB &= ~(1 << PB1_SERVOOUT); |
9 | _delay_ms(1000); |
10 | |
11 | } |
Das sollte ja die LED im 1s-Takt blinken lassen. Stattdessen scheint _delay_ms(1000) jedoch 5-6 Sekunden zu dauern. Stimmt etwas an der Taktfrequenz nicht? Ich habe die Fuse-Settings angesehen, dort ist konfiguriert: SUT_CKSEL: Int. RC Osc 8MHz, Start-up Ttime PWRDWN/RESET: 6CK/14CK + 65 Ich muss gestehen ich verstehe noch nicht ganz was das bedeutet? Mir siehts nach 8MHz Taktfrequenz aus? Danke, groki
...ich rate kurz ins blaue: der controller läuft noch auf 1Mhz mit dem internen taktoszillator wenn das so ist, würde der controller auch ohne externen quarz laufen (test!) du müßtest in dem fall die entsprechenden fuse-bits setzen, um den externen oszi einzuschalten (vorsicht, nichts falsches einstellen, sonst läuft der controller nicht mehr an!)
Bevor ich als AVR-Amateur anfange die Fuse-Bits zu verpfuschen: Das AVR-Studio sagt ja SUT_CKSEL: Int. RC Osc 8MHz, Start-up Ttime PWRDWN/RESET: 6CK/14CK + 65 heisst das nicht das er mit 8MHz läuft? Wenn ich recht ans Datenblatt erinnere werden die ATMEGA88 auch mit 8MHz ausgeliefert, oder? Die sind brandneu. Der AVR steckt im STK500 Board, ohne Quartz... Ich werd's mal mit 1MHz versuchen, danke!
Ich glaube Du hast recht, mit 1MHz scheint es zu klappen. Oh mann! Ich habe irgendwo gelesen 8MHz sei Standard bei Auslieferung...muss das mal checken. Werd nun mal nachlesen wie man 8MHz einstellt, falls jemand ne gute Referenz hat wär ich dankbar! (Bin ich auch jetzt schon, DANKE fürs helfen!!)
Lasse S. schrieb: > Er kann das einfach wegoptimieren, weil du nichts tust. Der Compiler > erkennt, dass die Schleife für den Programmablauf sinnlos ist. Nein darf er nicht, alle AVR Register sind als volatile definiert. Da eine Leseoperation auf TCNT0 gemacht wird, darf hier nicht wegoptimiert werden.
Ich hab mir auch schon mal einen verfused, kann von daher nicht wirklich sicher weiterhelfen. Man kann sowas außer hier auch im Bascom-Forum ( http://bascom-forum.de/ ) oder im AVR-Forum nachfragen. hier wäre was in der art, allerdings für Mega644er: http://bascom-forum.de/index.php/topic,3863.msg26546.html#msg26546
Datenblatt lesen!!!
1 | 8.2.1 Default Clock Source |
2 | The device is shipped with internal RC oscillator at 8.0MHz and with the |
3 | fuse CKDIV8 programmed, resulting in 1.0MHz system clock. |
Wie man das Teil auch ohne Fuse verstellen auf 8MHz bekommt steht auch da: Kapitel 8.11 und 8.12, insbesondere 8.12.2.
Oh man, ich hatte ja reingesehen hab aber vermutlich nur
1 | The device is shipped with internal RC oscillator at 8.0MHz |
"wer lesen kann ist klar im Vorteil"... Danke!
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.