Ach, es geht um Servoimpulse, alles klar.
Vielleicht wäre das eine Basis:
(Aus https://www.roboternetz.de/community...l=1#post522751)Code:// Servoansteuerung mit 16Bit-Timer1 (mit arexx cat16) mic 18.1.2011 // Die 8 Servos werden an Port B und C angeschlossen: // Servo0 - PB0 // Servo1 - PB1 // Servo2 - PC2 // Servo3 - PC3 // Servo4 - PC4 // Servo5 - PC5 // Servo6 - PC6 // Servo7 - PC7 #include <avr/io.h> #include <avr/interrupt.h> volatile uint8_t count_20ms; volatile uint16_t servo[9] ={1700, 1700, 1700, 1700, 1700, 1700, 1111, 1111, 40000}; // Servopositionen void sleep(uint8_t pause); // 1/50 Sekunde blockierende Pause int main(void) { cli(); // für 16MHz-ATMega16 TCCR1A = (0<<WGM11)|(0<<WGM10); // CTC-Mode 4 TCCR1B = (0<<WGM13)|(1<<WGM12); TCCR1B |= (0<<CS12)|(1<<CS11)|(0<<CS10); // prescaler /8 TIMSK = (1<<OCIE1A); // MatchCompare-Interrupt erlauben DDRB = 0b00000011; // Datenrichtung Servoausgänge setzen DDRC = 0b11111100; sei(); sleep(100); while(1) // Demo { cli(); servo[0]=2500; servo[1]=servo[2]=1600; sei(); sleep(50); cli(); servo[0]=servo[1]=servo[2]=1700; sei(); sleep(50); } return(0); } ISR(TIMER1_COMPA_vect) { static uint8_t nr=8; // Nummer des aktuellen Servos PORTB &= ~0b00000011; // alle Servoimpulse low PORTC &= ~0b11111100; if(nr < 3) // Impuls für Servo oder Pause? (8 Servos) { if(nr<2) PORTB |= (1<<nr); // Impulsleitung des aktuellen Servos else PORTC |= (1<<nr); // auf High setzen und OCR1A = servo[nr]; // Impulslänge in OCR1A laden servo[8] -= servo[nr]; // Impulslänge von der Pause abziehen nr++; // nächstes Servo } else { OCR1A = servo[8]; // servo[8] ist die Impulspause servo[8] = 40000; // Startwert 20ms laden nr = 0; // beim nächsten ISR-Aufruf Impuls // für Servo 0 erzeugen if(count_20ms) count_20ms--; // blockierende Pause aktiv? } } void sleep(uint8_t pause) // 1/50 Sekunde blockierende Pause { count_20ms=pause+1; while(count_20ms); }
Das Programm wurde für einen 16MHz-Mega16 geschrieben, sollte aber auch auf dem Mega32 laufen. Der Timer1 läuft im CTC-Mode mit Prescaler/8 von 0 bis 40000 in 20ms. Während eines Zyklus werden nacheinander jeweils die Impulse für bis zu 8 Servos erzeugt. Die Servopositionen sind in servo[0] bis servo[7] gespeichert, 2000 sind eine Millisekunde (0,001s). In servo[8] ist der Wert für das Zyklusende gespeichert, ein kleinerer Wert (muss aber größer als die Summe der Servos sein, z.B TCNT1+=10) erhöht die Wiederholfrequenz. Mit if(nr < 3) kann man die Anzahl der verwendeten Servos ändern.
Gruß
mic







Zitieren

Lesezeichen