Forum: Mikrocontroller und Digitale Elektronik SERVO und PWM


von M. Н. (Gast)


Lesenswert?

Hallo.
Habe folgendes Problem:
ich will einen Servo mit PWM ansteuern.
Dazu benötige ich ein PWM Signal mit 50Hz.
Habe mir folgende Formel ausgedacht:

Frequenz = Systemtakt / (Teiler * 510)

Habe alles versucht. Bekomme aber nie 50Hz hin. Da ich sonst Quarze mit 
völlig abnormalen Frequenzen bräuchte. Hoffe ihr könnt mir helfen. 
Benutze einen ATMEGA16.

P.S.: An den Externen Takteingang habe ich auch gedacht. Allerdings 
bräuchte ich dann einen kleinen avr, der die Frequenz erzeugt.

Danke im Voraus.

Gruß M.H.

von Bernd R. (Firma: Promaxx.net) (bigwumpus)


Lesenswert?

Wahrscheinlich sprichst Du von einem RC-Servo.

Du brauchst keinen 50Hz-Takt, es geht auch quasi jede andere Zykluszeit. 
Selbst der ATMEGA16 wird doch irgendwie einen ca. 20ms-Timer 
hinbekommen, um die Zykluszeit abzuwarten und dann einen passenden Puls 
zu timen.

von M. Н. (Gast)


Lesenswert?

Nei Habs probiert mit 24.5 Hz  (mit warteschleifen generiert) spinnt der 
Servo

von Floh (Gast)


Lesenswert?

M. H. schrieb:
> Nei Habs probiert mit 24.5 Hz  (mit warteschleifen generiert) spinnt der
> Servo

klar, die Servos wollen immer spätestens nach 20 ms einen Impuls.
Mit 24.5 Hz ist das aber nicht der Fall und das Servo weis nicht wohin.

Allerdings brauchst du hier eine PWM.
Periodendauer irgendwas zwischen 3 und 20 ms, On-Zeit zwischen 1 und 2 
ms, die Onzeit betimmt dabei die Stellung des Servos.
:-)

von Michael F. (startrekmichi)


Lesenswert?

Die Zauberabkürzung heißt CTC (siehe Datenblatt). Damit kannst du den 
Timer beliebig einstellen, weil er nicht mehr bis 255/65535 zählt, 
sondern bis zu einem beliebigen Wert.

Wenn du die Ansteuerung komplett in Hardware machen willst, nimm den 
Timer1 im FastPWM-Modus. In OCR1A kommt der berechnete Maximalwert und 
in OCR1B der Wert für die Pulslänge (du willst den Servo ja in 
verschiedene Positionen fahren können). Der Servo kommt an den OC1B-Pin. 
Im Betrieb musst du dann nur noch den OCR1B-Wert ändern.

Oder du stellst einen Timer per CTC auf ein Vielfaches der 50Hz ein und 
zählst dann per software durch.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Denke daran, dass die PWM im Bereich von 1ms...2ms noch wenigstens 8Bit 
Auflösung braucht, sonst kannst Du das Servo nicht ausreichend fein 
ansteuern.

von M. Н. (Gast)


Lesenswert?

Hab mal das Probiert.


Da ist der Servo voll durgedreht. Das geht nur mit exakt 50Hz.
1
.include <m16def.inc>
2
.cseg
3
.org $00
4
ldi r16, low(RAMEND)
5
ldi r17, high(RAMEND)
6
out spl, r16
7
out sph, r17
8
ldi r16, (1<<3)
9
out ddrb, r16
10
ldi r16, 0
11
out portb, r16
12
ldi r16, 50
13
out ocr0, r16
14
ldi r16,(1<<CS01) |(1<<cs00) | (1<<WGM00) | (1<<COM01)
15
out tccr0, r16
16
s:rjmp s

von M. Н. (Gast)


Lesenswert?

wenn ich das mit warteschleifen mache.

Dann mache ich für Mittelstellung 18ms low und 2ms high


Gruß M.H.

von Floh (Gast)


Lesenswert?

M. H. schrieb:
> Dann mache ich für Mittelstellung 18ms low und 2ms high

Was hast du für Servos? Normal ist das nicht, außer du hast falsch 
gemessen :-)
Hast du ein Oszi?
:-)

von M. Н. (Gast)


Lesenswert?

Der servo  fährt bei 1ms - 3ms immer an den rechtsanschlag.
Ja hab n Oszi

von M. Н. (Gast)


Lesenswert?

Dieses Programm fährt den servo exakt in mittelstellung:
1
s:
2
sbi portb,3
3
; ============================= 
4
;   Warteschleifen-Generator 
5
;     9600 Zyklen:
6
; ----------------------------- 
7
; warte 9594 Zyklen:
8
          ldi  R17, $0D
9
WGLOOP0:  ldi  R18, $F5
10
WGLOOP1:  dec  R18
11
          brne WGLOOP1
12
          dec  R17
13
          brne WGLOOP0
14
; ----------------------------- 
15
; warte 6 Zyklen:
16
          ldi  R17, $02
17
WGLOOP2:  dec  R17
18
          brne WGLOOP2
19
; ============================= 
20
cbi portb, 3
21
; ============================= 
22
;   Warteschleifen-Generator 
23
;     144000 Zyklen:
24
; ----------------------------- 
25
; warte 143994 Zyklen:
26
          ldi  R17, $CE
27
WGLOOP0s:  ldi  R18, $E8
28
WGLOOP1s:  dec  R18
29
          brne WGLOOP1s
30
          dec  R17
31
          brne WGLOOP0s
32
; ----------------------------- 
33
; warte 6 Zyklen:
34
          ldi  R17, $02
35
WGLOOP2s:  dec  R17
36
          brne WGLOOP2s
37
; ============================= 
38
39
40
rjmp s

von M. Н. (Gast)


Lesenswert?

.include <m16def.inc>
.cseg
.org $00
ldi r16, low(RAMEND)
ldi r17, high(RAMEND)
out spl, r16
out sph, r17
ldi r16, (1<<3)
out ddrb, r16
ldi r16, 0
out portb, r16
ldi r16, 100
out ocr0, r16
ldi r16,(1<<CS01) |(1<<cs00) | (1<<WGM00) | (1<<COM01)

out tccr0, r16
s:


rjmp s
  Das hier lässt ihn auch an einen punkt fahren. aber er zittert so und 
sobald ich das Taktsignal wegnehme verstellt er sich ein bisschen.

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.