mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SIMPELSTE Servo-"Steuerung"


Autor: groki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lasse S. (cowz) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht wird
while(TCNT0<(2000/8)); // wait 2ms

einfach wegoptimirt?

Gruß,
Lasse

PS: Auch wenn der Code kurz ist, Code-Tags wären nett.

Autor: groki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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"...!

Autor: groki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lasse S. (cowz) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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-Tu...

Gruß
Lasse

Autor: groki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: groki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, ich hab jetzt mal eine LED statt Servo angeschlossen, und folgenden 
einfachen Code:

#define F_CPU 8000000UL  // 8 MHz

...

while(1){
  PORTB |= (1 << PB1_SERVOOUT);
  _delay_ms(1000);
  PORTB &= ~(1 << PB1_SERVOOUT);
  _delay_ms(1000);
    
}


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

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...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!)

Autor: groki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: groki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!!)

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Bertrand_H (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.msg265...

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Datenblatt lesen!!!
8.2.1 Default Clock Source
The device is shipped with internal RC oscillator at 8.0MHz and with the
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.

Autor: groki (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh man, ich hatte ja reingesehen hab aber vermutlich nur
The device is shipped with internal RC oscillator at 8.0MHz
"wer lesen kann ist klar im Vorteil"...

Danke!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.