Forum: Mikrocontroller und Digitale Elektronik PWM mit ATmega8 und Servo


von Boombofer (Gast)


Lesenswert?

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
}

von Bernhard G. (thisamplifierisloud)


Lesenswert?

Probier auch mal ein anderes Servo.

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
Noch kein Account? Hier anmelden.