Cytat:
Z obsługi przerwania wyrzuciłem zbędny kod.
Wpisałem TCNT0=250; i zlicza bardzo szybko.
Zlicza bardzo szybko, ale obawiam się, że niedokładnie. 6 taktów to za mało nawet na tak krótką procedurę obsługi przerwania. Pisząc w C nie widzimy tego, ale samo wejście w procedurę to 4 takty + wyjście (RETI) 4 takty. Do tego zwykle w procedurze obsługi przerwania występuje jakieś odkładanie na stos używanych rejestrów (przynajmniej SREG musi być zapamiętany) - po 2 takty na rejestr, później zdejmowanie ze stosu - też po 2 takty na rejestr. Samo wczytanie z RAM wartości zmiennej 'a', inkrementowanie i ponowne zapamiętanie to jakieś 10 taktów (chyba, że kompilator umieścił zmienną 'a' w rejestrach, co jest raczej mało prawdopodobne). Wniosek:
przerwania są częściej niż czas trwania procedury obsługi, więc nie wszystkie zostaną obsłużone i tym samym wartość zmiennej 'a' będzie
nieprawidłowa. Nie masz prawdopodobnie teraz tego jak sprawdzić, ale uwierz mi na słowo. Jeśli potrzebujesz aż tak dużej szybkości, to ta metoda nie zda egzaminu. Nawet zastosowanie trybu CTC (odeszłaby wtedy konieczność ustawiania stanu licznika - można pominąć 'TCNT0 = 250;') też nie wystarczy.
Nie wiem jakie prędkości obrotowe chcesz mierzyć, ale przy większych obrotach lepiej zastosować tarczę z większą ilością otworów i zliczać impulsy z czujnika fotooptycznego w jednostce czasu np. 1s. Obliczenie prędkości obrotowej będzie wtedy wyglądało mniej więcej tak:
(ilość zliczonych impulsów) / ( (czas zliczania [s]) * (ilość otworów w tarczy) ) [obr./s]
Dla zwiększenia dokładności i zakresu pomiarów można użyć 16-bitowego timera (właściwie to raczej 'countera') taktowanego sygnałem zewnętrznym, czyli impulsami z czujnika.
Ta metoda daje małe dokładności w zakresie niskich obrotów.
Inna opcja to zrezygnowanie z inkrementowania zmiennej wewnątrz obsługi przerwania. Można wyzerować licznik (trzeba użyć 16-bitowego bo 8-bitowy będzie miał zbyt mały zakres i co za tym idzie - dokładność) w momencie pojawienia się zbocza opadającego i odczytać jego wartość do zmiennej 'a' w momencie pojawienia się zbocza narastającego. W pętli głównej przeliczasz 'a' na prędkość obrotową i wyświetlasz na LCD.
Przykładowo, wykorzystując Twoją technikę:
ISR(INT0_vect)
{
if (flaga==0)
{
TCNT1=0;
MCUCR= (1<<ISC00) | (1<<ISC01); //przerwanie wyzwalane zboczem narastającym __|--
flaga=1;
}
else if (flaga==1)
{
a = TCNT1;
MCUCR=1<<ISC01; //1. ustawiam przerwanie wyzwalane zboczem opadającym --|__
flaga=0;
}
}
// na początku funkcji 'main' należy włączyć taktowanie timera 1
// bez preskalera
TCCR1B = (1<<CS10);
// później nie trzeba go wyłączać, wystarczy zerować licznik
W tym przypadku nie należy stosować otworów, a raczej jakieś "wypustki" przesłaniające czujnik tylko przez jakiś mały kąt w stosunku do kąta odsłonięcia, najlepiej niezbyt dużą ilość (tych "wypustek"), większą od 1, żeby była możliwość dobrego wyważenia tarczy. Ewentualnie można zmienić procedurę tak, aby timer zliczał czas w momencie przesłonięcia czujnika (a nie jak w naszym przypadku powyżej - czas odsłonięcia) i wtedy można zastosować otwory.
Kąty odsłonięcia i przesłonięcia czujnika należy dobrać odpowiednio do zakresu mierzonych prędkości obrotowych. Przykładowo, aby uzyskać większą dokładność przy wyższych obrotach należy zastosować jak największy kąt "zliczania timera". Z kolei zbyt duży kąt może spowodować przepełnianie timera przy niższych obrotach.
No i wykonanie tarczy musi być dosyć precyzyjne (i symetryczne) jeśli oczekujesz precyzyjnych pomiarów. Poprzednia metoda (ze zliczaniem impulsów w jednostce czasu) nie wymaga dużej precyzji.
Obliczenie prędkości przy wykorzystaniu tej metody wyglądałoby mniej więcej tak:
(kąt odsłonięcia czujnika [rad]) * F_CPU [Hz] / ( 2 * PI * (ilość zliczonych impulsów) ) [obr./s]
Zastosowanie tej metody daje mniejsze dokładności przy wyższych obrotach.
Zależnie od tego, jaki zakres prędkości będziesz mierzył, należy wybrać odpowiednią metodę. Nie ma uniwersalnego rozwiązania. Jeśli zakres będzie zbyt duży (np. od kilku obr./min do kilkunastu tysięcy obr./min) trzeba zastosować obydwie metody z możliwością zmiany zakresu, żeby uzyskać satysfakcjonującą dokładność pomiaru.
Mam nadzieję, że nie zagmatwałem za bardzo
Dodano po 47 [minuty]: Cytat:
Jeśli przysłonię czymś czujnik, zaczyna liczyć, jeśli odsłonię, przestaje i zaraz wyświetla wartość zmiennej a.
A ja przyjąłem, że jest dokładnie odwrotnie. Który schemat z tych dwóch przez Ciebie przedstawionych zastosowałeś? Ja sądziłem, że ten po lewej. W każdym razie ja bym tak podłączył. Jeśli zastosowałeś ten po prawej, to będzie działał odwrotnie, czyli musisz "odwrócić" wszystkie wyrazy związane z przesłonięciem lub odsłonięciem czujnika w tekście, który napisałem powyżej (lub zmienić podłączenie czujnika

).