Witam.
Chciałem zrobić obrotomierz na Atmega128, w tym celu podaję impulsy na INT1, jako podstawa czasu służy Timer2. Zliczam impulsy Timera2 w czasie pomiędzy dwoma zboczami opadającymi z INT1. Na początek podaję przebieg z generatora, i tu zaczyna się problem.
Przebieg z generatora ma stabilna częstotliwość, ale już podprogram od Int1 wywoływany jest chaotycznie i wskazania także są chaotyczne. Program obsługuje jeszcze wyświetlacze LED multipleksowo na Timer0, sterując katodami poprzez cały jeden port, anody mam przypisane różnie (tylko 4 szt - 4wyświetlacze).
Czym może być spowodowane takie chaotyczne zachowanie układu?
Obrotomierz na Atmega128 - niestabilne wskazania
-
keruseykaryu
Niby INT ma pierwszeństwo przed przerwaniami od liczników,ale jak widać, nie jest to prawda. Za dużo obliczeń włożyłem w Interrupt Service od Timer0, który obsługuje wyświetlanie. Musze przepisać program i wrzucić obliczenia w pętlę główną. Doszedłem do tego po wywaleniu większości programu i pozostawieniu tylko przerwań liczących i INT i wskazania były stabilne (sprawdzałem sygnał na nodze, której wpisałem Toggle w przerwaniu od INT, bo wyświetlanie całe wywaliłem)
-
atelszewski
- Użytkownik
- Posty: 143
- Rejestracja: 12 sie 2005, 9:36
- Lokalizacja: Banie
Witam,
Generalnie, w czasie wykonywania procedury danego przerwania, wszystkie inne przerwania są zablokowane. Zachowanie to można zmienić poprzez odpowiedni kod obsługi ISR, wtedy będziemy mieli do czynienia z przerwaniami zagnieżdżonymi, czyli możliwością wywołania procedury obsługi przerwania, w czasie gdy wykonuje się procedura obsługi innego przerwania. Jednak temat przerwań zagnieżdżonych wcale nie jest taki prosty i oczywisty jak mogłoby się to wydawać. Zawsze jeśli możesz, staraj się nie zagnieżdżać przerwań.
Jeśli producent nie popełnił błędu w krzemie, to jest to prawda.Niby INT ma pierwszeństwo przed przerwaniami od liczników,ale jak widać, nie jest to prawda.
No właśnie! A w czesie tego ISR przerwania są zablokowane globalnie, również te od INTx.Za dużo obliczeń włożyłem w Interrupt Service od Timer0, który obsługuje wyświetlanie.
Generalnie, w czasie wykonywania procedury danego przerwania, wszystkie inne przerwania są zablokowane. Zachowanie to można zmienić poprzez odpowiedni kod obsługi ISR, wtedy będziemy mieli do czynienia z przerwaniami zagnieżdżonymi, czyli możliwością wywołania procedury obsługi przerwania, w czasie gdy wykonuje się procedura obsługi innego przerwania. Jednak temat przerwań zagnieżdżonych wcale nie jest taki prosty i oczywisty jak mogłoby się to wydawać. Zawsze jeśli możesz, staraj się nie zagnieżdżać przerwań.
-
keruseykaryu
Szczególnie w bascomie, bo pewnie w tym piszesz. Jak rzeczywiście piszesz w bascom to tam niestety przerwania są proste, ale mają szczegóły, o których jeśli nie wiesz to masz przechlapane. Pierwszy i najważniejszy od czasu zgłoszenia do czasu wykonania mija sporo czasu. Dobra jakieś dziesiątki mikrosekund, ale to i tak dużo.M@ciej pisze:Nie zamierzam zagnieżdżać przerwań, w ogóle jest to dla mnie temat egzotyczny.
Same priorytety to pryszcz. W przerwaniach, co mają być przerywane trzeba tylko włączyć na początku znowu przerwania. Teraz masz priorytety zgodne z krzemem. Jak jeszcze będziesz włączać i wyłączać te które ci są potrzebne to już masz swoje priorytety. Wszyćko!
ps. Te utraty sesji do szału mnie doprowadzą. Weźcie sobie inny serwer postawcie na forum co?
Tak, piszę w Bascomie. Przerwania (globalne) zgłaszam poprzez "Set Sreg.7". Mam tylko 2 przerwania wewnętrzne i 1 zewnętrzne. Mój błąd polegał na tym, że w przerwanie od wyświetlania powrzucałem operacje arytmetyczne na zmiennych typu Single, jest tam rzutowanie itp., ot procedura konwertująca zmienną single na kod wyświetlaczy 7-seg i jeszcze kilka innych. Po wrzuceniu tego w główną pętlę, na wyświetlaczach pojawiły się krzaczki, gdyż wyświetlana była wartość pośrednia z obliczeń. Zastanawiam się, jak to zsynchronizować.