-
Es scheint so zu sein, dass der compare-interrupt den Timer nicht ausschaltet. Aus welchen Gründen auch immer.
Die Rücksetzung des Timers auf 0 ist aber auf jeden Fall richtig. (TCNT2 = 0)
Ich habe es grad getestet, und es ist tatsächlich so, dass der compare-Interrupt garnicht auftritt. Jetzt muss nur noch geklärt werden, warum nicht.
Gruß, Yaro
-
Hahahaha, natürlich tritt er nicht auf! hahahaha
so ein Anfängerfehler hahaha.
man muss ihn erstmal in der Mask freigeben.
Man sieht....Anfängerfehler macht man immer =)
Ich versuche es gleich, ob es dann funktionieren wird =)
Gruß, Yaro
-
Nunja.....Der interrupt funktioniert jetzt zwar, allerdings funktioniert jetzt der Rest nicht =)
Ich guck nochma woran das liegen kann....
Gruß, Yaro
-
Ich habe den Fehler gefunden: Hardware Fast PWM funktioniert folgendermaßen: bei überganz von TOP zu BOTTOM wird auf HIGH gesetzt, und beim compare-match auf LOW.
Mit dem Programm haben wir jetzt das "HIGH setzen" übersprungen, was natürlich scheiße ist....
Hier ist das fertige Programm (8MHz)
Code:
#include <avr/io.h> //I/O Port definitions
#include <avr/interrupt.h> //Interrupt macros
#include <util/twi.h> //TWI STATUS
/*----------------------------------------------------------------------------------------*/
//PWM
/*----------------------------------------------------------------------------------------*/
//750 = 1.5ms
volatile int schulter= 750;
volatile int huefte = 750;
volatile int knie = 750;
void pwm_init(int schulter, int huefte, int knie); //PWM_init Funktion
//void pwm_chance(int schulter, int huefte, int knie);//Anpassen der PWM grössen
/*----------------------------------------------------------------------------------------*/
//MAIN AUFRUF
/*----------------------------------------------------------------------------------------*/
int main(void)
{
DDRB = 0xFF; //B... AUSGANG
PORTB &= ~((1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3)); //B.. Low
sei(); //Globale Interupts zulassen
pwm_init(schulter, huefte, knie); //PWM initialisieren
while(1)
{
}
}
ISR(TIMER2_COMP_vect) //Überlaufinterupt Timer2
{
TCCR2 &= 0x00; //Löschen von Timer2
}
ISR(TIMER1_CAPT_vect) //Captureinterupt Timer1
{
TCNT2 = 255;
TCCR2 = (1<<WGM20) | (1<<WGM21) |(1<<COM21) | (1<<CS22) | (1<<CS20); //Setzten von Timer2
}
void pwm_init(int schulter, int huefte, int knie) //PWM initialisieren
{
TIMSK |= (1<<TICIE1) | (1<<OCIE2); //Interupt initialisieren, freischalten
//Timer 1 (Port 0/1)
TCCR1A = (1<<COM1A1)| (1<<COM1B1); //Clear OC on Comp Match when up-count, set downcount
TCCR1B = (1<<WGM13) | (1<<CS11) ; //PWM Phase abd Freq Correct. Prescaler 8
ICR1 = 10000; //Periodendauer Servo 20ms
OCR1A = schulter; //Servosignal (Port 0, Schulter)
OCR1B = huefte; //Servosignal (PORT 1, Hüfte)
//Timer 2 (Port 2)
TCCR2 = (1<<WGM20)| (1<<WGM21) | (1<<COM21) | (1<<CS22) | (1<<CS20); //Fast PWM
OCR2 = (knie/8); //Servosignal (Port2, Knie)
}
-
=D>
Es funktioniert. Das Signal ist sehr sauber und auch die angeschlossenen Servos funktionieren. Echt toll. Vielen herzlichen dank.
Jetzt muss ich mir die Sache noch genauer ansehen damit ich nachvollziehen kann woran es lag.
-
Sehr schön!
Achte übrigens darauf, dass du beim dritten Servo immer 1 abziehen musst (statt 1500 nur noch 1499), weil der Timer nicht bei 0, sondern bei sozusagen -1 anfängt
Gruß, Yaro
-
werd ich beachten, danke schön