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


von groki (Gast)


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

von Lasse S. (cowz) Benutzerseite


Lesenswert?

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.

von groki (Gast)


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"...!

von groki (Gast)


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

von Lasse S. (cowz) Benutzerseite


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-Tutorial#Warteschleifen_.28delay.h.29

Gruß
Lasse

von groki (Gast)


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.

von groki (Gast)


Lesenswert?

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

von Bertrand_H (Gast)


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!)

von groki (Gast)


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!

von groki (Gast)


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!!)

von Simon K. (simon) Benutzerseite


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.

von Bertrand_H (Gast)


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.msg26546.html#msg26546

von ... (Gast)


Lesenswert?

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.

von groki (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.