Witajcie
Napotkałem następujący problem - Mam układ komunikujący się szeregowo z procesorem w sposób następujący:
1. Układ wywołuje przerwanie
2. Odbieram dane statusu od układu
3. Wychodzę z przerwania
i to działa.
Problem zaczyna się jeżeli odebrane dane statusu wymuszają w procesorze kolejne operacje z użyciem układu. Ponieważ idzie to tak:
1.Układ wywołuje przerwanie
2.Odbieram dane statusowe w wywołanym przerwaniu
3.Wysyłam do układu żądanie wykonania operacji
4.Układ po wykonaniu operacji zgłasza przerwanie
5.Wysyłam do układu żądanie wykonania operacji
6.Układ po wykonaniu operacji zgłasza przerwanie
itd.... aż do końca obsługi.
I tu zaczyna się problem. Układ działa dość szybko więc powyższe punkty wykonuję w obsłudze pierwszego pojawiającego się przerwania (pkt.1) czekając programowo bitwait-em na wykonanie zadanej układowi przez procesor operacji (pkt.4 i 6). W efekcie po obsłudze całego cyklu komunikacji po kolejnych przerwaniach programowych ze tak je nazwętypu pkt.4 i 6 pozostaje ustawiona sprzętowa flaga przerwania zewnętrznego w procesorze czyli po wyjściu z obsługi przerwania procesor od razu ponownie w nie wchodzi.
Wg. mojej teorii sprawę powinno załatwić zwykłe resetowanie rejestru flag ExternalInterruptsFlagRegister EIFR. Niesety nie działa to zupełnie. Próbowałem i prostego Reset EIFR jak i wstawek asm jednak nie chce mi to zadziałać. Flaga się nie zeruje - wiem to z tąd ze układ w kółko wchodzi w przerwanie jak i po resecie flagi napisałem funkcję if testującą tą flagę. Warunek ten za każdym razem wskazuje ze bit EIFR.0 (bo INT0 używam) jest ustawiony.
Końcowo powtórzę że jeśli komunikuję się z układem w taki sposób ze nie korzystam z jego opcji zgłaszania końca zadanej pracy to wszytko działa super. problem zaczyna się jeśli w trakcie obsługi przerwania pojawi się kolejne żądanie przerwania (pkt.4 i 6) którego nie potrafię na ten moment wyzerować wychodząc z przerwania.
Macie jakieś pomysły jak to ugryźć?
Z góry dziękuję
Dodano:
Co ciekawe usiłowałem jeszcze programowo zamiast zerować to ustawiać flagę EIFR.0 tak aby wywołać przerwanie. Niestety bezskutecznie. Tak jakbym w ogóle nie miał programowego dostępu do rejestru EIFR.
Przetestowałem też chyba wszystkie możliwe składnie...
set INTF0
set EIFR.0
asm
sbi $38,0
end asm
Napotkałem następujący problem - Mam układ komunikujący się szeregowo z procesorem w sposób następujący:
1. Układ wywołuje przerwanie
2. Odbieram dane statusu od układu
3. Wychodzę z przerwania
i to działa.
Problem zaczyna się jeżeli odebrane dane statusu wymuszają w procesorze kolejne operacje z użyciem układu. Ponieważ idzie to tak:
1.Układ wywołuje przerwanie
2.Odbieram dane statusowe w wywołanym przerwaniu
3.Wysyłam do układu żądanie wykonania operacji
4.Układ po wykonaniu operacji zgłasza przerwanie
5.Wysyłam do układu żądanie wykonania operacji
6.Układ po wykonaniu operacji zgłasza przerwanie
itd.... aż do końca obsługi.
I tu zaczyna się problem. Układ działa dość szybko więc powyższe punkty wykonuję w obsłudze pierwszego pojawiającego się przerwania (pkt.1) czekając programowo bitwait-em na wykonanie zadanej układowi przez procesor operacji (pkt.4 i 6). W efekcie po obsłudze całego cyklu komunikacji po kolejnych przerwaniach programowych ze tak je nazwętypu pkt.4 i 6 pozostaje ustawiona sprzętowa flaga przerwania zewnętrznego w procesorze czyli po wyjściu z obsługi przerwania procesor od razu ponownie w nie wchodzi.
Wg. mojej teorii sprawę powinno załatwić zwykłe resetowanie rejestru flag ExternalInterruptsFlagRegister EIFR. Niesety nie działa to zupełnie. Próbowałem i prostego Reset EIFR jak i wstawek asm jednak nie chce mi to zadziałać. Flaga się nie zeruje - wiem to z tąd ze układ w kółko wchodzi w przerwanie jak i po resecie flagi napisałem funkcję if testującą tą flagę. Warunek ten za każdym razem wskazuje ze bit EIFR.0 (bo INT0 używam) jest ustawiony.
Końcowo powtórzę że jeśli komunikuję się z układem w taki sposób ze nie korzystam z jego opcji zgłaszania końca zadanej pracy to wszytko działa super. problem zaczyna się jeśli w trakcie obsługi przerwania pojawi się kolejne żądanie przerwania (pkt.4 i 6) którego nie potrafię na ten moment wyzerować wychodząc z przerwania.
Macie jakieś pomysły jak to ugryźć?
Z góry dziękuję
Dodano:
Co ciekawe usiłowałem jeszcze programowo zamiast zerować to ustawiać flagę EIFR.0 tak aby wywołać przerwanie. Niestety bezskutecznie. Tak jakbym w ogóle nie miał programowego dostępu do rejestru EIFR.
Przetestowałem też chyba wszystkie możliwe składnie...
set INTF0
set EIFR.0
asm
sbi $38,0
end asm