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.
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.
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. :-)
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.
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.
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 |
wenn ich das mit warteschleifen mache. Dann mache ich für Mittelstellung 18ms low und 2ms high Gruß M.H.
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? :-)
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 |
.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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.