Mark Ziegler schrieb:
> Bei der oben genannten Frequenz von 400kHz(T=2500ns) und einem Timertakt
> von 16MHz(externer Quarz; Periodendauer=62,5ns) ergibt sich somit
> rechnerisch ein Timerwert von 40.
Es bedeutet aber auch, dass alle 40 Takte ein AUfruf dieser ISR
erfolgt
1 | ISR(INT0_vect)
|
2 | {
|
3 | x=TCNT1L; //Counterwert speichern
|
4 | TCNT1L=0x00; //reset Lowteil des Registers
|
5 | static uint8_t i=0; //Hilfsvariable
|
6 | if (i>0) //ersten Wert verwerfen
|
7 | {
|
8 | u8_timerwert[i-1]=x; //Arrayelemente mit Timerwerten beschreiben
|
9 | }
|
10 | i++;
|
11 | if (i==6) //Abbruchbedingung
|
12 | {
|
13 | GICR &= (0<<INT0); //ISR deaktivieren
|
14 | Ausgabe();
|
15 | }
|
16 |
|
17 |
|
18 | }
|
und die wird höchst wahrscheinlich nicht einen Durchlauf in 40 Takten
zustande bringen. Durch den Funktionsaufruf zwingst du den Compiler alle
Register zu sichern. Und schon alleine das kostet dir einige Taktzyklen.
Halte dich an die einfache Regel: man macht keine derartigen Ausgaben in
einer ISR. Leg das Zeug in die Hauptschleife, die ISR setzt ein Flag,
wenn es Zeit ist die Ausgabe zu starten und gut ists. Dann ist deine ISR
kurz
1 | volatile uint8_t i=0; //Hilfsvariable
|
2 |
|
3 | ISR(INT0_vect)
|
4 | {
|
5 | x=TCNT1L; // Counterwert speichern
|
6 | TCNT1L=0x00; // reset Lowteil des Registers
|
7 |
|
8 | u8_timerwert[i] = x; // Arrayelemente mit Timerwerten beschreiben
|
9 |
|
10 | i++;
|
11 | if( i == 5 )
|
12 | {
|
13 | GICR &= ~(1<<INT0); //ISR deaktivieren
|
14 | i = 0;
|
15 | }
|
16 | }
|
und du kannst die Timinganforderungen erfüllen, dass die ISR nicht mehr
als 40 Takte brauchen darf.
PS: Warum verwendest du nicht den Input Capture? Genau dafür ist der
gedacht. Und die Interrupt Latenz wirst du damit auch automatisch los.