Hallo Leute,
versuche gerade mit einem atmega88 einen Servo anzusteuern. Der Servo
soll nacheinander verschiedene Positionen anfahren. Es soll eine von mir
festgelegte Wartezeit ("i") zwischen den Positionen geben.
Was funktioniert:
- PWM mittels Timer. Periodendauer stimmt (Oszi), Positionsänderungen
durch manuelles setzen der "posi"-Variable macht der Servo.
- die debounce Funktion funktioniert auch, die Variable "schalter" gibt
an, ob Kippschalter an oder aus ist. Geprüft mit LED.
- Es gibt keine Fehler beim kompilieren, nix raucht^^
Wo es hängt:
Wenn ich den µC mit Schalterstellung "aus" programmiere, fährt der Servo
in die Stellung 1500. Schalte ich den Schalter ein, fährt der Servo in
die erste Position vom Ablaufprogramm und bleibt dort für immer.
Warum will er nicht weiter?
Ist mein erstes µC-Projekt, wenn euch also irgendwelche "don'ts"
auffallen, bitte sagen.
Vielen Dank, mfG
1 | #define F_CPU 8000000UL
|
2 |
|
3 | #include <avr/io.h>
|
4 | #include <avr/interrupt.h>
|
5 | #include <util/delay.h>
|
6 |
|
7 | static int pressed_confidlvl=0;
|
8 | static int released_confidlvl=0;
|
9 | static volatile unsigned int i=0;
|
10 | static volatile int posi=1500;
|
11 | static volatile unsigned int schrittnr=4;
|
12 |
|
13 | int debounce(int a);
|
14 | void ablauf(int n);
|
15 |
|
16 | int main(void)
|
17 | {
|
18 | //Timer1 (16bit) für PWM einstellen
|
19 | DDRC |= (1 << PC0); //Servopin als Ausgang
|
20 | TCCR1A |= (1 << WGM11); //siehe eine Zeile weiter unten
|
21 | TCCR1B |= (1 << CS11) | (1 << WGM12) | (1 << WGM13); //prescaler auf clk/8 & fastpwm mode mit ICR1 als TOP
|
22 | TIMSK1 |= (1 << TOIE1); //Overflow Interrupt einschalten
|
23 | ICR1 = 19999; //Neues TOP-ende des Zählers festgelegt. Insgesamt 20 000 entspricht bei F_CPU 8MHz, prescaler clk/8, einer dauer von 20ms oder 50Hz
|
24 | sei();
|
25 |
|
26 | DDRC &= ~(1 << PC2); //Pin für Schalter auf Eingang setzen & Pullup aktivieren
|
27 | PORTC |= (1 << PC2);
|
28 | DDRC |= (1 << PC3); //SchalterkontrollLED-pin auf Ausgang setzen
|
29 |
|
30 | int schalter=0; //Gibt an ob Schalter an=1 oder aus=0. Wird durch debounce-Funktion gesetzt.
|
31 |
|
32 | while(1)
|
33 | {
|
34 | schalter=debounce(schalter);
|
35 |
|
36 | if (schalter == 1)
|
37 | {
|
38 | PORTC |= (1 << PC3); //wenn schalter 1 dann LED an
|
39 | ablauf(1);
|
40 | }
|
41 | else
|
42 | {
|
43 | PORTC &= ~(1 << PC3); // wenn schalter 0 dann LED aus
|
44 | i=0;
|
45 | }
|
46 |
|
47 | //PWM für Servo
|
48 | if (TCNT1 >= 500 && TCNT1 <= 3000) //Zeitabschnitt Pegel=1 von PWM //außerdem einschränkung der abfragezeit durch max und minimale servoposition
|
49 | {
|
50 | if (TCNT1 >= posi && bit_is_set(PORTC, PINC0))
|
51 | {
|
52 | PORTC &= ~(1 << PC0); //Pegel zurück auf 0 setzen
|
53 | }
|
54 | }
|
55 | if (TCNT1 < 500 || TCNT1 > 3000) //Zeitabschnitt Pegel=0 von PWM
|
56 | {
|
57 | }
|
58 | }
|
59 | }
|
60 |
|
61 | ISR(TIMER1_OVF_vect) //wird alle 20ms aufgerufen, da
|
62 | {
|
63 | PORTC |= (1 << PC0);
|
64 |
|
65 | if (i > 0)
|
66 | {
|
67 | i--; //alle 20ms i um eins dekrementieren bis 0 erreicht
|
68 |
|
69 | if ((i == 0) && (schrittnr > 0))
|
70 | {
|
71 | schrittnr--; //am Ende der durch i definierten Wartezeit: schrittnr erniedrigen
|
72 | }
|
73 | }
|
74 | }
|
75 |
|
76 |
|
77 | int debounce(int a)
|
78 | {
|
79 | int pressed=a;
|
80 |
|
81 | if (bit_is_clear(PINC,PC2))
|
82 | {
|
83 | pressed_confidlvl++;
|
84 | if (pressed_confidlvl >= 10000 && pressed == 0) //Grenze für confidencelevel noch nicht sinnvoll überlegt.
|
85 | {
|
86 | pressed_confidlvl = 0;
|
87 | pressed = 1;
|
88 | }
|
89 | }
|
90 | if (bit_is_set(PINC, PC2))
|
91 | {
|
92 | released_confidlvl++;
|
93 | if (released_confidlvl >= 10000 && pressed == 1)
|
94 | {
|
95 | released_confidlvl = 0;
|
96 | pressed = 0;
|
97 | }
|
98 | }
|
99 | return pressed;
|
100 | }
|
101 |
|
102 | void ablauf(int n) //n gibt die Nummer des Programms an, welches in der if abfrage danach definiert wird
|
103 | {
|
104 | if (n == 1)
|
105 | {
|
106 | if (schrittnr == 4)
|
107 | {
|
108 | posi = 800;
|
109 | i = 100; // i = 100 entspricht 2 sek Wartezeit
|
110 | }
|
111 | if (schrittnr == 3)
|
112 | {
|
113 | posi = 1400;
|
114 | i = 100;
|
115 | }
|
116 | if (schrittnr == 2)
|
117 | {
|
118 | posi = 2000;
|
119 | i = 100;
|
120 | }
|
121 | if (schrittnr == 1)
|
122 | {
|
123 | posi = 1000;
|
124 | i = 100;
|
125 | }
|
126 | if (schrittnr == 0)
|
127 | {
|
128 | posi = 800;
|
129 | i = 100;
|
130 | }
|
131 | }
|
132 | }
|