Witam
Kod jak poniżej służy do zliczania czasu trwania jednego impulsu (ta funkcja działa prawidłowo) oraz do zliczania czasu (w celu zliczania ilości impulsów na jednostkę czasu).
volatile unsigned char pomiar = 0;
volatile uint32_t cw_impuls,impuls = 0;
unsigned char sreg;
float tc1;
char czas[8];
void Inicjalizacja(void)
{
LCD_init(); // Inicjalizacja wyświetlacza
sei(); // Włączenie obsługi przewań
MCUCR = 0; // Zerowanie rejestru MCUCR
MCUCR |= (1<<ISC11)|(0<<ISC10); // Wyzwolenie przerwania zboczem opadającym
GICR |= (1<<INT1); // Załączenie przerwania na INT1
TCCR1A = 0; // T/C1 w trybie czasomierza
TCNT2 = 0; // Zerowanie rejestru TCNT2
TCCR2 = 0; // Zerowanie rejestru TTCR2
TCCR2 |= (1<<WGM21)|(1<<WGM20)|(1<<CS21); // T/C2 w trybie CTC z preskaler 8
OCR2 = 0; // Zerowanie rejestru OCR2
OCR2 = 125; // 125imp = 1ms
TIMSK = 0; // Zerowanie rejestru TIMSK
TIMSK |= (1<<OCIE2); // Załączenie przerwania gdy TCNT2 = OCR2
}
SIGNAL (SIG_INTERRUPT1)
{
if (pomiar==0)
{
TCNT1 = 0; // Zerowanie czasomierza T/C1
TCCR1B |= (1<<CS10)|(1<<CS12); // Zalaczenie timera1 - preskaler ck/1024
MCUCR = 0; // Zerowanie rejestru MCUCR
MCUCR |= (1<<ISC11)|(1<<ISC10); // Przestawienie przerwania na zbocze narastajace
pomiar = 1;
}
else
{
TCCR1B &= ~((1<<CS12)|(1<<CS10)); // Wylaczenie timera1
MCUCR = 0; // Zerowanie rejestru MCUCR
MCUCR |= (1<<ISC11)|(0<<ISC10); // Przestawienie przerwania na zbocze opadajace
pomiar = 0;
}
}
SIGNAL (SIG_OUTPUT_COMPARE2)
{
++cw_impuls;
impuls=(cw_impuls*2)/1000;
}
int main( void )
{
Inicjalizacja();
while(1)
{
LCD_xy(0,0);
sreg = SREG; // Zapis ustawień rejestru SREG
cli(); // Wyłączenie obsługi przerwań
tc1 = TCNT1; // Zapis rejestru TCNT1 do zmiennej tc1
SREG = sreg; // Ustawienie rejestru SREG
dtostrf(tc1*1.024,8,0,czas); // Konwersja float do ascii
LCD_putstr_P(PSTR("TCNT1: "));
LCD_putstr(czas);
LCD_xy(0,1);
LCD_putstr_P(PSTR("Sekundy: "));
LCD_putint(impuls,10);
}
}
Do zliczania czasu trwania pojedyńczych impulsów używam timera1, do zliczania czasu próbuję użyć timera2.
Atmega jest taktowana z wewnętrzym oscylaotrem 1Mhz timer 2 pracuje w trybie CTC i przy zliczeniu do 125 (1ms) wywołuje przerwanie w którym zliczane są przerwania które się powinne pojawiać równo co 1ms.
I teraz zliczony czas spóźnia mi się ok 2-3s na każdą minutę i dlaczego wartość:
impuls=(cw_impuls*2)/1000;
Wiem że przerwania z INT1 mogą się nakładać w czasie z przerwaniami z timera2 i powodować błędy, ale na chwile obecną bez uruchamiania timera1 timer2 źle zlicza.
Timer2 domyślnie ma zliczać czasy tylko do 60s (jak wcześniej wspomniałem w celu zliczania ilości impulsów na minutę) więc się zadowoliłbym dokładnością <1s.
Z góry dziękuję za wszelkie rady i pomoc

--
pozdrawiam
demeus
Dodano po 13 [minuty]:
Co ciekawe kiedy kod do wyświetlania wrzucę do funkcji obsługi przerwania:
SIGNAL (SIG_OUTPUT_COMPARE2)
{
++cw_impuls;
impuls=(cw_impuls*4)/1000;
LCD_xy(0,1);
LCD_putstr_P(PSTR("Sekundy: "));
LCD_putint(impuls,10);
}
Zliczony czas znowu dodatkowo musze mnożyć tym razem przez 4 by otrzymać sekundy, ale mimo wszystko opóźnienie dalej występuje.
--
pozdrawiam
demeus