Ich habe nochmal rumprobiert und ein paar Versionen geschrieben:
Version 1:
Bei Compare Match A und B werden Interrupts ausgelöst, die die neuen
Werte in den Timer übernehmen sollen:
1 | ISR(TIMER1_COMPA_vect)
|
2 | {
|
3 | OCR1A = Impuls1; //neuen Impulszählerstand nehmen
|
4 | }
|
5 |
|
6 | //Interrupts
|
7 | TIFR |= TCF1A; //Compare Match A Interrupt
|
8 | TIFR |= OCF1B; //Compare Match B Interrupt
|
Der Mainloop enthält die Tasterabfrage:
1 | while(1)
|
2 | {
|
3 | if (!(PIND & (1<<PD2)))
|
4 | {
|
5 | Impuls1+=5;
|
6 | }
|
7 | else if (!(PIND & (1<<PD3)))
|
8 | {
|
9 | Impuls1-=5;
|
10 | }
|
11 | }
|
Das Servo rührt sich aber kein bisschen...
Nächster Versuch:
Timer 0 zählt bis Höchststand und löst OVF aus. Darin die Tasterabfrage
1 | //Servosteuerung Drehleiter
|
2 | //Servo 1 an PB1 (OC1A)
|
3 | //Servo 2 an PB2 (OC1B)
|
4 |
|
5 | #define F_CPU 3686400
|
6 |
|
7 | #include <avr/io.h>
|
8 | #include <avr/interrupt.h>
|
9 |
|
10 | volatile static unsigned int Impuls1; //Impulslänge Servo2
|
11 | volatile static unsigned int Impuls2; //Impulslänge Servo2
|
12 | const unsigned int Periodendauer = 10000; //Periodendauer
|
13 |
|
14 | unsigned int Position1; //Impulszählerstand Servo1 generell
|
15 | unsigned int Mittelstellung1 = 1000; //Impulszählerstand Mittelstellung Servo1
|
16 |
|
17 | unsigned int Position2; //Impulszählerstand Servo2 generell
|
18 | unsigned int Mittelstellung2 = 1000; //Impulszählerstand Mittelstellung Servo2
|
19 |
|
20 | ISR(TIMER0_OVF_vect)
|
21 | {
|
22 | if (!(PIND & (1<<PD2)))
|
23 | {
|
24 | Impuls1+=15;
|
25 | }
|
26 | else if (!(PIND & (1<<PD3)))
|
27 | {
|
28 | Impuls1-=15;
|
29 | }
|
30 | OCR1A = Impuls1; //neuen Impulszählerstand für Servo1 nehmen
|
31 |
|
32 | if (!(PIND & (1<<PD4)))
|
33 | {
|
34 | Impuls2+=15;
|
35 | }
|
36 | else if (!(PIND & (1<<PD5)))
|
37 | {
|
38 | Impuls2-=15;
|
39 | }
|
40 | OCR1B = Impuls2; //neuen Impulszählerstand für Servo2 nehmen
|
41 | }
|
42 |
|
43 | int main(void)
|
44 | {
|
45 | //Allgemeine Initialisierungen
|
46 | DDRB = 0xFF; //PORTB Ausgang für Servos
|
47 | DDRD = 0x00; //PORTD Eingang für Taster
|
48 | PORTD = 0xFF; //PORTD Pullup-Widerstände
|
49 |
|
50 |
|
51 | //Positionskonfiguration
|
52 | Impuls1 = Mittelstellung1; //Servo1 Mittelstellung
|
53 | Impuls2 = Mittelstellung2; //Servo2 Mittelstellung
|
54 |
|
55 | //Timer1-Konfiguration
|
56 | ICR1 = Periodendauer;
|
57 |
|
58 | TCCR1B |= (1 << CS10); //Timer1 Vorteiler 1
|
59 |
|
60 | TCCR1A |= (1 << COM1A1); //OCR1A bei Compare Match setzen und bei ICR1
|
61 | //löschen
|
62 | TCCR1A |= (1 << COM1B1); //OCR1B bei Compare Match setzen und bei ICR1
|
63 | //löschen
|
64 |
|
65 | TCCR1A |= (1 << WGM11);
|
66 | TCCR1B |= (1 << WGM12);
|
67 | TCCR1B |= (1 << WGM13); //WGM11:13 für Fast PWM mit Obergrenze ICR1
|
68 |
|
69 | OCR1A = Impuls1; //OC1A geht low bei Zählerstand von Impuls1
|
70 | OCR1B = Impuls2; //OC1B geht low bei Zählerstand von Impuls2
|
71 |
|
72 | //Timer0-Konfiguration
|
73 | TCCR0 |= (1<<CS02); //Timer0 Vorteiler 1
|
74 | TIMSK |= (1<<TOIE0); //Interrupt bei Timer0 Overflow
|
75 |
|
76 | sei(); //Interrupts werden zugelassen
|
77 |
|
78 | //mainloop;
|
79 | while(1)
|
80 | {
|
81 |
|
82 | }
|
83 | return(1);
|
Das Servo 2 an PB2 (OCR1B) funktioniert gut.
Allerdings gibt es beim rechten Anschlag das Problem, dass der Servo
kurz davor noch in den regulären Schritten "fährt", dann jedoch
plötzlich unkontrolliert 20° weiterspringt.
Servo 1 rührt sich aber garnicht...
Gruß Steffen