MezData-Logo Creative Commons License 625 :AVR: Modellbauservo ansteuern mit Timer

Schlüsselwörter: Atmel, AVR, Servo, PWM, Modellbau

Aufgabenstellung

MIttels eines ATtiny2313 soll ein Modellbauservo angesteuert werden. Dazu wird zunächst der 16-bit Timer/Counter1 with PWM verwendet.
[ ATtiny2313] Seite 88ff.

Demo

Ansteuerung von Modellbau Servos

Carson ServoImpulsdiagrammEin Modellbauservo sollte spätestens alle 20 ms einen Steuerimpuls bekommen. Die Impulslänge ist proportional zum Stellwinkel des Servos. Sie bewegt sich typischerweise zwischen 1,0 und 2,0 ms. Für den Modellbauer interessant ist vor allem die Impulsdauer der Mittelstellung des Servos - hier 1,5 ms.

Die erste Überlegung betrifft das Timing zur Erzeugung des PWM-Signals.
Der Timer wird mit einem vorgeteilten von der CPU-Frequenz abgeleiteten Signal betrieben. Mögliche Teilverhältnisse sind: 1,8,64,256,1024. Der Controller hat einen internen Oszillator mit folgenden wählbaren Frequenzen: 1,2,4,8 MHz.

Timer und Pulsweitenmodulation

TimingdiagrammDer Servo erhält alle 20ms einen Impuls zwischen 1.0ms und 2.0ms Dauer. Der Timer wird daher mit 1 MHz, dem Systemtakt getaktet.

Gewählt 1 MHz mit Vorteiler 1:1.

Betriebsart Fast PWM Mode siehe Seite 98ff. Der Timer zählt von 0 bis zu einem einstellbaren TOP Wert und springt dann wieder auf 0. Ein Ausgang kann beim Sprung von TOP auf 0 gesetzt und bei Erreichen eines einstellbaren Wertes OCR1A wieder rückgesetzt werden.

OCR1A als TOP. OCR1B als Pulsweite. Ausgang ist PB4 (OC1B).

Einstellungen bei Initialisierung

Register Bit 7 6 5 4 3 2 1 0 Beschreibung
TCCR1A Bedeutung COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10 Ausgang OC1B bei 0 setzen und bei OCR1B löschen
Wert 0 0 1 0 0 0 1 1

Waveform Generation Mode: Fast PWM mit OCR1A als TOP

TCCR1B Bedeutung ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
Wert 0 0 0 1 1 0 0 1 Keine Vorteilung Timer mit CPU-CLK (No prescaling)
TIMSK Bedeutung TOIE1 OCIE1A OCIE1B - ICIE1 OCIE0B TOIE0 OCIE0A Keine Interrups notwendig
Wert 0 0 0 0 0 0 0 0

Anschluß des Servos

D0 1 2 D1
D2 3 4 D3
Signal D4 5 6 D5
D6 7 8 D7
GND GND 9 10 VCC +Servo
ATtiny2313 STK200 I/O Port B

Initialisierung 1,5ms Impuls

#include <avr/io.h>
int main(){
  DDRB = 0b00010000; // PB4 als Ausgang
  TCCR1A = 0b00100011; // Ausgang OC1B bei 0 setzen und bei OCR1B loeschen
  TCCR1B = 0b00011001; // Waveform Generation Mode: Fast PWM it OCR1A als Top, Timer mit CPU-CLK 
  OCR1A = 19999; // alle 20ms
  OCR1B = 1500;  // Impulslaenge 1,5ms
  while (1); // Endlosschleife
}

Initialisierung und Anfahren der Endpositionen

Quellcode [Servo.c]
// *** Servo 1.0 (c) Oliver Mezger 30.11.2010

#include <avr/io.h>
#include <util/delay.h>

unsigned char keyOld= 0,keyEnter,keyExit; // Tastaturereignisse

void keyCheck(){                // Abfragen der Tasten
  unsigned char keyTest,tmp;
  keyEnter = 0, keyExit = 0;
  keyTest = ~PIND & 0b01111111; // Einlesen und zurechtschieben
  if (keyOld != keyTest){       // hat sich was getan
    _delay_ms(10);              // Prellen abwarten
    tmp = ~PIND & 0b01111111;   // nochmal Einlesen und zurechtschieben
    if (tmp == keyTest){        // ist es stabil?
      keyEnter = (~keyOld) & keyTest; // steigende Flanke !alt und neu
      keyExit = keyOld & (~keyTest);  // fallende Flanke alt und !neu
      keyOld = keyTest;
    }
  }
}

unsigned int tasteInWert(unsigned char n){ // Umwandeln in Wert
  switch (n){
  case 4: return 2000;
  case 2: return 1500;
  case 1: return 1000;
  default: return 1500;
  }
}

int main(){
  unsigned char i;
  DDRB = 0b00010000;   // PB4 als Ausgang
  TCCR1A = 0b00100011; // Ausgang OC1B bei 0 setzen und bei OCR1B loeschen
  TCCR1B = 0b00011001; // Waveform Generation Mode: Fast PWM it OCR1A als Top, Timer mit CPU-CLK 
  OCR1A = 19999;       // Impulsabstand 20ms
  OCR1B = 1500;        // Impulslaenge  1,5ms
  while (1){           // stetiges Abfragen der Tasten
    keyCheck();
    if (keyEnter){
      OCR1B= tasteInWert(keyEnter);
    }
  } 
}

Aufgaben

Erstellen Sie eine Lösung, die ohne PWM auskommt.

Erstellen Sie eine Lösung mit 8Bit Timer.

Das Servo soll folgenden Weg immer abfahren: 1000ms, 2s; 1200ms, 2s; 1800ms, 3s; zurück zu 1000ms.