Hallo zusammen,
ich versuche schon ein paar Abende verzweifelt, mit meinem myAVR-Board
und ATmega 8 einen Servo (Modelcraft RS-2 von conrad) anzusteuern
(angeschlossen an Port C). Ich habe leider nicht wirklich Erfahrung mit
Timern/Interrupts und habe mir bisher folgenden Code zusammengebaut.
Leider komme ich nicht weiter, der Servo dreht - egal wie ich die
Pulsweite verändere - nach rechts an den Anschlag. Ich wollte zwei
Taster (angeschlossen an Port D) verwenden, um die Drehrichtung zu
ändern. Wäre nett, wenn ihr mir ein paar Hinweise geben könntet. Ich
hoffe ihr müsst nicht kotzen, wenn ihr den Code lest :-)
Vielen Dank schonmal!
1 | /*
|
2 |
|
3 | ATmega8 @ 4 MHz
|
4 |
|
5 | */
|
6 |
|
7 |
|
8 | #define F_CPU 3686400L // Systemtakt in Hz
|
9 |
|
10 | #include <stdint.h>
|
11 | #include <string.h>
|
12 | #include <avr/io.h>
|
13 | #include <avr/interrupt.h>
|
14 |
|
15 |
|
16 | // Timer 1 Output COMPARE A Interrupt
|
17 |
|
18 | ISR(TIMER1_COMPA_vect) {
|
19 |
|
20 | PORTC = 0x01;
|
21 |
|
22 | }
|
23 |
|
24 | // Timer 1 Output COMPARE B Interrupt
|
25 |
|
26 |
|
27 | ISR(TIMER1_COMPB_vect) {
|
28 |
|
29 | PORTC = 0x00;
|
30 | }
|
31 |
|
32 |
|
33 |
|
34 | int main(void) {
|
35 |
|
36 |
|
37 | DDRD=0x00; // Port D als Eingang
|
38 | PORTD=0x0C; // Pull-Up
|
39 |
|
40 | DDRC = 0xFF; // Port C als Ausgang
|
41 |
|
42 | OCR1B = 0x0000; // Wenn Counter = 0, Interrupt auslösen und PORTC = 0x00 setzen
|
43 |
|
44 | ICR1 = 0x0120; // Counter zählt 14,4 (3686/256) Schritte pro ms
|
45 | // Zykluszeit = 20ms => Counter zählt bis 288 = 0x0120
|
46 |
|
47 |
|
48 | TCCR1A = (1<<WGM11) | (1<<WGM10); // 10 Bit PWM, keine Pins schalten
|
49 | TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS12); // Mode 12 (CTC) + Clk/256
|
50 |
|
51 | TIMSK |= (1<<OCIE1A); // Interrupt freischalten
|
52 | TIMSK |= (1<<OCIE1B);
|
53 |
|
54 | sei(); // Interrupts gloabl einschalten
|
55 |
|
56 |
|
57 | do {
|
58 |
|
59 | if (!(PIND&0x04)) {
|
60 |
|
61 | OCR1A = 0x0112; // Counter zählt in 19 ms bis 274 = 0x0112 => 1 ms Impuls
|
62 | // PORTC = 0x02;
|
63 |
|
64 | }
|
65 |
|
66 | else if (!(PIND&0x08)) {
|
67 |
|
68 | OCR1A = 0x0103; // Counter zählt in 18 ms bis 259 = 0x0103 => 2 ms Impuls
|
69 | // PORTC = 0x04;
|
70 |
|
71 | }
|
72 | }
|
73 |
|
74 | while (1);
|
75 |
|
76 | }
|