Ich habe heute ein C Programm erarbeitet, mit dem man bis zu 12 Servos unter Verwendung eines 8-Bit Timers ansteuern kann.
Code:
// Example source code, that may be used to control up to 6 servo
// motors using a single 8 bit timer.
// On each timer overflow, the next channel is handled, which allows us
// to multiplex between 6 channels. The timer compare register A is used
// to control the puls width. You could add code to use the timer compare
// register B which would allow handling of up to 12 channels.
// With a 20Mhz clock, the duty cycle is 19,8ms
// and the pulse width is pwm_value*00.128ms.
// With a 16Mhz clock, the duty cycle is 25ms
// and the pulse width is pwm_value*00.16ms.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// Values for up to six PWM channels.
// On each channel, the special value 0 can be used to switch the signal off.
volatile uint8_t pwm_value[6];
// The timer compare interrupt ends the current PWM pulse
ISR(TIMER2_COMPA_vect) {
PORTC &= ~(1+2+4+8+16+32); // set all 6 PWM outputs to low
PORTB |= 4; // status LED off
}
// The timer overflow interrupt starts a PWM pulse,
// on each interrupt, another channels is handled.
ISR(TIMER2_OVF_vect) {
static uint8_t channel=0;
uint8_t value=pwm_value[channel];
if (value>0) {
switch (channel) {
// If you need less than 6 channels, then comment out the unused lines below
case 0: PORTC |= 1; break;
case 1: PORTC |= 2; break;
case 2: PORTC |= 4; break;
case 3: PORTC |= 8; break;
case 4: PORTC |= 16; break;
case 5: PORTC |= 32; break;
}
OCR2A=value;
PORTB &= ~4; // status LED on
}
if (++channel==6) { // Do not change the 6, even when you need less than 6 channels!
channel=0;
}
}
int main() {
// Initialize I/O Pins
DDRB |= 4; // status LED
DDRC |= 1+2+4+8+16+32; // six PWM outputs
// Initialize timer 2, normal mode, prescaler 256, interrupt on overflow and compare match A.
TCCR2A = 0;
TCCR2B = (1<<CS22) | (1<<CS21);
TIMSK2 = (1<<TOIE2) | (1<<OCIE2A);
sei();
// Move servo on channel 5 to three different positions repeatedly.
// The following values are designed for the servo ES-05 and 20Mhz CPU clock.
while (1) {
pwm_value[5]=38;
_delay_ms(2000);
pwm_value[5]=108;
_delay_ms(2000);
pwm_value[5]=188;
_delay_ms(2000);
}
return 0;
}
Lesezeichen