Peinlicherweise, weil mir ein Ansatz fehlt - wenn du den (TIMER1_CAPTURE_vect)-Ansatz meinst
Code:
ISR(TIMER1_OVF_vect)
{
z++;
TIFR = (1<<TOV1); //Beim Überlauf von Timer1 und dem anschließenden Interrupt erfolgt eine Zurücksetzung auf Null
}
ISR(TIMER1_CAPTURE_vect)
{
}
int main(void)
{
// Definition von Ein- und Ausgängen des uC Boards
DDRB = 0xFE; // Mit Ausnahme des ICP1-Pins alles als Ausgang
DDRC = 0xFF; // PORTC als Ausgang - über PORTC werden die jeweiligen Segmente einer 7-Seg. Anzeige gesteuert
DDRD = 0xFF; // PORTD als Ausgang
PORTC = 0b00000000;
TIMSK = (1<<TICIE1) | (1<<TOIE1); // ICR1 und Ovf aktiviert
TCCR1B = (1<<ICES1) | (1<<CS10) // Trigger bei steigender Flanke, Vorteiler = 1
sei(); // Interruptbehandlung ein
while(1) // unendliche Schleife
{
zaehler1_aktuell = TCNT1; // der aktuelle Timer1 Wert wird in zaehler1_aktuell kopiert
zaehler1_ovf = z; // Anzahl der Überläufe wird in zaehler1_ovf kopiert
z= 0;
TCNT1 = 0;
if ((zaehler1_ovf==0)&&(zaehler1_aktuell==0))
{
freq = 0;
}
else
{
// Die abschließende Summierung aller Anteile samt Kompensation von Abweichungen
freq = (uint16_t) (F_CPU/(0.5+(65535.0*zaehler1_ovf + zaehler1_aktuell)));
}
zahl_ausgeben(freq);
}
return 0;
}
Mit einem Interrupt sichere ich den Timer1 beim Überlauf.
Wenn das TIMER1-Capture Ereignis eintritt,k nann ich doch nicht den Zählerstand auswerten, weil es möglicherwise erst die erste Flanke war?
MfG Nik
- - - Aktualisiert - - -
So, habe hier mal was eingefügt - einfache Zählvariable, die inkrementiert wird, sobald ein Timer1-Capture Ereignis eintrifft. Erst beim zweiten Durchlauf (Zähvariable=2) werden die Timerwerte gesichert und angewendet.
Code:
#define F_CPU 16000000 // uC läuft mit 16MHz
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned short z=0;
volatile unsigned short c=0;
int zaehler1_aktuell = 0; // aktueller Timer0 Wert
int zaehler1_ovf = 0; // Anzahl der Überläufe des Timer0
uint16_t freq = 0;
ISR(TIMER1_OVF_vect)
{
z++;
TIFR = (1<<TOV1); //Beim Überlauf von Timer1 und dem anschließenden Interrupt erfolgt eine Zurücksetzung auf Null
}
ISR(TIMER1_CAPTURE_vect)
{
//if(TIFR&(1<<ICF1))
c++;
}
int main(void)
{
// Definition von Ein- und Ausgängen des uC Boards
DDRB = 0xFE; // Mit Ausnahme des ICP1-Pins alles als Ausgang
DDRC = 0xFF; // PORTC als Ausgang - über PORTC werden die jeweiligen Segmente einer 7-Seg. Anzeige gesteuert
DDRD = 0xFF; // PORTD als Ausgang
PORTC = 0b00000000;
TIMSK = (1<<TICIE1) | (1<<TOIE1); // Interrupts akivieren, Capture und Overflow
TCCR1B = (1<<ICES1) | (1<<CS10); // Input Capture Edge, kein Prescaler
sei(); // Interruptbehandlung ein
while(1) // unendliche Schleife
{
if (C==2)
{
zaehler1_aktuell = TCNT1; // der aktuelle Timer1 Wert wird in count kopiert
zaehler1_ovf = z; // Anzahl der Überläufe wird in zaehler1_ovf kopiert
z= 0;
TCNT1 = 0;
if ((zaehler1_ovf==0)&&(zaehler1_aktuell==0))
{
freq = 0;
}
else
{
// Die abschließende Summierung aller Anteile samt Kompensation von Abweichungen
freq = (uint16_t) (F_CPU/(0.5+(65535.0*zaehler1_ovf + zaehler1_aktuell)));
}
zahl_ausgeben(freq);
c=0;
}
}
return 0;
}
Würde das eine optimale Lösung darbieten?
MfG Nik
Lesezeichen