Pepisoft was du doch willst ist mit einem Timer mehrer Zeiten messen. Also Ultraschall, rc5 und PWM von deinem Kompass. Der Timer1 hat hat nur einen Input Capture Pin (für srf04). Du kannst aber die Externen Interrupt Pins benutzen.
Ich hab hier mal Code:
Code:
// geändert auf 8MHZ
#include <io.h>
#include <avr/delay.h>

#define US_PORT            PORTD
#define US_PORT_RICHTUNG   DDRD
#define US_PIN             PD7         // Der Pin kommt zum Trigger-Puls Eingang  

volatile unsigned int us_zeit=0;
volatile unsigned int zeit_int0=0,zeit_int1=0;      // geändert

SIGNAL(SIG_INTERRUPT0)
{
    zeit_int0=TCNT1;     // geändert
    TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10);     // Timer wieder aus
    TCNT1=0;
}

SIGNAL(SIG_INTERRUPT1)
{
    zeit_int1=TCNT1;       // geändert
    TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10);     // Timer wieder aus
     TCNT1=0;
}

SIGNAL(SIG_INPUT_CAPTURE1)         // Interrupt für US Zeitmessung
{
    us_zeit=ICR1; 
    TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10);     // Timer wieder aus
    TCNT1=0;
}               

unsigned char start_us_messung(void)           // Ultraschallmessung
{
    unsigned char wert,wert_in_cm;
	        
    // PD6 ist Input Capture Pin beim ATMega8, hier kommt der Echo-Pulse Ausgang hin
    TIMSK|= (1<<TICIE1);          // Input Capture Interrupt enable	
    TCCR1B&=~(1<<ICES1);   // Fallende Flanke für Input Capture
    US_PORT|=(1<<US_PIN);       // Trigger-Puls Eingang high
    _delay_us(15);          // Laut Datenblatt Trigger-Puls min 10us auf high
    _delay_us(15);           // Laut Simulator ist wartet _delay_us() nur die 
                                    // hälfte der Zeit
    US_PORT&=~(1<<US_PIN);   // Trigger-Puls Eingang wieder auf low
    _delay_us(185);                  // Erst wird ein 200us langer 40kHz Burst vom srf04 gesendet
    _delay_us(185);
    TCCR1B|=(1<<CS11); // Prescaler 8,     startet Timer
    while(us_zeit==0);        // Warten bis Ergebnis
    if(us_zeit>19000)       // Dann kein Objekt vor den Sensor
    {
         wert=0;
         us_zeit=0;
         return wert;
    }
    else
    {
       wert=172*us_zeit/10000;   // wert ist nun in cm       
       us_zeit=0;
       return wert;
    }
}


// Zeitmessung mithilfe von Externem Interrupt 0 und Timer1
unsigned long long star_zeitmessung_int0(unsigned char flag) // flag = 1 fallende Flanke generiert Interrup
{                                                               // flag = 2 gegenteil
    unsigned long long wert;
    if(flag==1)
       MCUCR|=(1<<ISC01);
    if(flag==2)
       MCUCR=(1<<ISC01|(1<<ISC00);
    GICR |=(1<<INT0);         // Externer Interrupt an
    TCCR1B|= (1<<CS11); // Timer an, Prescaler 8 damit Zeitäuflösung genau 1 micro sekunde !!!   geändert
    while(zeit_int0==0);     // Warten bis Ergebnis
    wert=zeit_int0;         // Wert in micro sekunden
    zeit_int0=0;        // Wieder auf 0 setzen für nächste Messung
    return wert;
}

// Zeitmessung mit Externem Interrupt1 und Timer1
unsigned long long start_zeitmessung_int1(unsigned char flag)
{
    unsigned long long wert;
    if(flag==1)
    MCUCR|=(1<<ISC11);
    if(flag==2)   
       MCUCR=(1<<ISC11) | (1<<ISC10);
    GICR|=(1<<INT1);
    TCCR1B|= (1<<CS11);  // Timer an, Prescaler 8   geändert
    while(zeit_int1==0);
    wert=zeit_int1;
    zeit_int1=0;
    return wert;
}

void main (void)
{
    unsigned char wert;
    unsigned long long wert1,wert2;
    US_PORT_RICHTUNG|=(1<<US_PIN);         // US_PIN auf Ausgang
    wert=start_messung();
    wert1=start_zeitmessung_int0();
    wert2=start_zeitmessung_int1();
}
Damit kann man mit einem Timer alle deine drei Ereignisse messen. Die Funktionen start_zeitmessung_intX() geben dir nur die Zeit in micro sekunden zurück. Was du damit machst (umrechnen in Grad bei Kompass, rc5 usw.) ist dir überlassen. In deinem Fall muss halt z.B. den Out Pin von deim TSOP auf einen der Externen Interrupt Pins von deinem ATMega. Allerdings weis ich immer noch nicht was passiert wenn der Timer mehr als 1mal durchläuft, also nach 262,144 millisekunden. Um den sozusagen Höchsmesswert zu erhöhen kann man den Prescaler in den Funktionen start_zeitmessung_intX() verändern und in den Interrupts in den Zeilen zeit_intX=TCNT1*4; das *4 dementsprechend ändern. Hoffe man hats verstanden.
Gruß Muraad

EDIT: nochmal geändert, das mit TCCRB1 und TICIE1

EDIT: Code funktioniert nicht richtig. Bitte in den Thread schauen:
https://www.roboternetz.de/phpBB2/vi...?p=67114#67114