Zitat Zitat von BlackDevil
Code ist immer interessant ...
... dabei wollen wir mal festhalten, dass ich im Prinzip immer noch Anfänger bin - ich beschäftige mich grad ein knappes Jahr mit µC´s und mit der Sprache C erst seit letztem Dezember. Beschäftigen heißt ja auch nicht "können".

Zitat Zitat von BlackDevil
... obgleich deine Variablen etwas schwierig zu entziffern sind (teilweise) ...
Du loos, ih wohn im beirischn Schwobn, des isch bei iis des Allgei - obwol i a Auslenda bi. Do wiatz scho a bizzle a drAnpassung liaga. (Kann ich bei Bedarf in die eine oder andere europäische Sprache übersetzen).

Zuerst muss man mal einen Timer initialisieren. Ich mach das mit dem Timer2, das ist der Timer mit der höchsten Interrupt-Priorität - also der, der als erster bedient wird! Der Timer2 wird bei mir wie folgt initialisiert - denk dran, ich arbeite mit dem mega168 und einem 20MHz-Takt, bei anderen Takten und Zeitschnippsel muss entsprechend angepasst werden. Hier kann ich übrigens nix für die Variablen - die sind im doc vorgeschrieben.
Code:
/* ============================================================================== */
/* ===  Initialisierung fuer Timer2 mega168 ===================================== */
void TC2TMR_init(void)                  // Init Tmr/Cntr 2, 8-Bit auf 20 kHz = 50 µs
{	     
    TCCR2A |= (1<<WGM21);               // Timer im CTC-Mode, Top=OCR2A   doc S 157
    TCCR2B |= (1<<CS21);		// Prescaler 1/8 / Clock <- CPU	  doc S 158
    OCR2A = 124;                        // Preset 125 für 50µs bei 20Mhz  
    TIMSK2 |= (1<<OCIE2A);		// Tmr/Cntr2 CompareA interrupt enabled
}     
/* ============================================================================== */
Da ich gerade beim Initialisieren bin, initialisiere ich auch gleich die beiden
externen Interrupts:
Code:
/* ============================================================================== */
/* ===  Initialisierung fuer EXT_INT0/1 auf Pin 4+5/PD2,3 bei m168  ================
$002 jmp SIG_INTERRUPT0 ; IRQ0 Handler   _VECTOR(1)
$004 jmp SIG_INTERRUPT1 ; IRQ1 Handler   _VECTOR(2)              ================ */
void XTI_0_1_init( void )	
{				//Initialisiere beide Interrupts auf rising edge
				//  d.h. EICRA ISC00,01,10+11 auf 1 (doc,S68)
    EICRA |= (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00);
    EIMSK  |= (1<<INT1)|(1<<INT0);	//  und erlaube diese I´s in EIMSK
// Initialisierung der Zeiten:  // Der Kürze wegen hier nur für Kanal 0
  Iz_diff0     = 0;             // Differenz zwischen dem aktuellen und dem
                                //   vorhergehenden Interrupt auf Kanal 0
  Iz_xseci0    = 0;             // Aktueller Zeitwert (Stand des 50µsec-Zählers)
                // Lies die Variable mal so: Integer Zeit "X" (regelungstechnisch
                //   wird mit "X" der Ist-Wert bezeichnet sec => in Zeiteinheiten,
                //   aber eben nicht sec sondern 50 µsec, i => istwert 0 .. Kanal
  Iz_xsecv0    = 0;             // Vorhergehender Zeitwert auf Null initialisieren
}
/* ============================================================================== */
Damit meine Zeiteinheit = 50 µs-Zeitscheiben ausgewertet wird, gibts ne ISR, die diese 50µs-Zeitschnippsel hochzählt:
Code:
/* ============================================================================== */
/* ===  Nicht unterbrechbare ISR für timer2 ===================================== */
/* Routine zählt hoch im Takt 20 kHz = 50 µs.
    ==> Eine Zeiteinheit ist also 50 µs ! Der Zählerwert wird von den ISR für
	EXT_INT0 und ~INT1 ausgelesen und den Werten Iz_yseci zugewiesen ......   */
ISR(TIMER2_COMPA_vect)          // Vektor 7
{
  if (Izeit_1 < 60000)          //Timer bis 60 000 ==> 3 sec Datenerfassung möglich
    Izeit_1 ++;                 //  und Izeit_1 bleibt in der uint16-Grenze
  else
  {   
    Izeit_1 = 0;		// ansonsten: Rückstellen auf Null
  }         
}         
/* ============================================================================== */
Das Auslesen der Zeitdauer erfolgt in einer ISR die bei fallender Flanke am Pin (siehe Routine) ausgelöst wird:
Code:
/* ============================================================================== */
/* ===  Nicht unterbrechbare ISR für EXT_INT0 auf Pin 46/PD2/mega168  =========== */
/* Routine rechnet den Zeitbedarf vom vorhergehenden zum jetzigen Interrupt aus,
   dieser Wert wird z.B. von der Regelung ausgelesen (nur dumm, wenn das erst nach
   dem nächsten Interrupt passiert - das ist bei mir aber nicht der Fall! Nennt sich
   Softwareengineering *ggggggg*
     Der zugehörige Motor auf PD7/PB0 = re,li und PB1 Geschwind./PWM              */
  ISR(INT0_vect)                // hiess mal: ISR(SIG_INTERRUPT0)
{                               // 
    Iz_xseci0 = Izeit_1;		//Weise Iz_xsec1 dem akt. Timerwert zu
    Iz_diff0 = Iz_xseci0-Iz_xsecv0;	//Neue Zeit-Differenz0 ausrechnen
    Iz_xsecv0 = Iz_xseci0;		//der aktuelle Zeitwert wird "Alter"
}
/* ============================================================================== */
So, das ist die ganze Sache. Wie bereits erwähnt, bei mir läufts - und die Coladose läuft mit zwei getrennten Motoren prächtig geradeaus. Achtung: es gibt sicher mehrere und auch bessere Möglichkeiten und verständlichere Variablen *gggg*.

Jetzt hoffe ich nur, dass ich nichts vergessen habe und nicht irgendeine Zeile entfernt habe, die für Deine Zwecke eher verwirrend wäre.

Viel Erfolg

Viel Glück.