Hallo µC-Freunde,
ich habe mal wieder ein Problem.
Und zwar möchte ich mich an diesem verschneiten Sonntag mit Servos
beschäftigen. Dazu habe ich einen GWS IQ-200MG neben mir stehen und die
Impulsleitung an PB1 meines AtMega8 angeschlossen. Den µC fahre ich bei
1MHz internal Clock.
Soweit so gut.
Folgendes habe ich mir gedacht:
Der Servo erwartet ein PWM Signal mit einer Periodendauer von 20ms und
darin einen Impuls von 1-2ms.
Um das zu realisieren habe ich das Datenblatt des Mega durchforstet und
herausgefunden, dass ich den 16bit Timer benötige.
Der Timer zählt also von 0 an zu zählen, dabei soll er high an PB1
(OC1A) führen. Nach 1000 Takten (also 1ms) soll er low führen - er muss
demnach einen Compare Match Interrupt ausführen - darf dabei aber nicht
zurückgesetzt werden.. Dann soll er bis 20.000 (20ms) zählen und erneut
bei null anfangen - also Overflow-Interrupt.
Hier nun mein nicht funktionstüchtiger Code:
1 | /***********************************/
|
2 | /* Servo-Test */
|
3 | /* 31.01.10 */
|
4 | /* F_CPU 1000000 */
|
5 | /***********************************/
|
6 |
|
7 | #include <avr/io.h>
|
8 | #include <avr/interrupt.h>
|
9 |
|
10 |
|
11 | volatile unsigned char comp, overflow;
|
12 |
|
13 | /***********************************/
|
14 | /* init_servo function */
|
15 | /* sets registers */
|
16 | /***********************************/
|
17 | void init_servo()
|
18 | {
|
19 | //fast pwm 10bit
|
20 | TCCR1A |= (1 << COM1A1) | (1 << WGM10) | (1 << WGM11) | (1 << WGM12);
|
21 | // prescaler 1
|
22 | TCCR1B |= (1 << CS10);
|
23 |
|
24 | //set top
|
25 | ICR1 = 20000; //20ms
|
26 |
|
27 | //drive to position
|
28 | OCR1A = 1000; //1ms - left stop
|
29 |
|
30 | }
|
31 |
|
32 | /***********************************/
|
33 | /* main function */
|
34 | /***********************************/
|
35 | int main()
|
36 | {
|
37 | //set DataDirectionRegisters
|
38 | DDRB |= (1 << PB1);
|
39 |
|
40 | // enable global interrupts
|
41 | sei();
|
42 |
|
43 | //start
|
44 | PORTB |= (1 << PB1);
|
45 |
|
46 | //call servo function
|
47 | init_servo();
|
48 |
|
49 | //endless loop
|
50 | while(1)
|
51 | {
|
52 | if( (comp == 1) || (overflow == 1) )
|
53 | {
|
54 | PORTB ^= (1 << PB1);
|
55 | comp = 0;
|
56 | overflow = 0;
|
57 | }
|
58 |
|
59 | }
|
60 | return 0;
|
61 | }
|
62 |
|
63 |
|
64 | /***********************************/
|
65 | /* InterruptServiceRoutine */
|
66 | /***********************************/
|
67 | ISR(TIMER1_COMPA_vect)
|
68 | {
|
69 | comp = 1;
|
70 | }
|
71 |
|
72 | ISR(TIMER1_OVF_vect)
|
73 | {
|
74 | overflow = 1;
|
75 | }
|
Vielleicht noch zur Erläuterung:
nutze ich, damit ich das Bit toggeln kann.
Ein Oszilloskop besitze ich leider nicht und kann daher auch nicht
sagen, was gerade an PB1 anliegt.
Ich verstehe einfach nicht, was daran falsch ist. Stehe ich gerade voll
auf dem Schlauch oder wo liegt der Fehler?
Ich hoffe Ihr könnt mir helfen.
Danke schon im Voraus.
Grüße
mateit