Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[mega16][C] Przerwania timera vs reszta kodu - blad programu

Myrek1 02 Mar 2009 17:12 1300 3
  • #1 02 Mar 2009 17:12
    Myrek1
    Poziom 23  

    Witam.
    Natrafiłem dziś na problem z przerwaniem. Mianowicie mam DS18B20, LCD, UART i timery. Program wygląda tak, że temperatura z DSa jest wyświetlana na LCD, wszystko gra. Mam też przerwanie, w którym co sekundę wysyłane jest 6 bajtów do kompa (przez UART). Przerwanie jest od Timera co 1 sekundę. Wszystko gra do czasu. W pewnym momencie program sie "wywala", nie chodzi pomiar temp.i LCD. Wg mnie przyczyną jest to, że w czasie np zapisu do 1-wire występuje to przerwanie, jest wykonywane (wysylanie 6 bajtow do UARTa troche trwa) i jest powrót do 1-wire. Ale wtedy już czas np zapisu na 1-wire upłynął i program czeka w pętli na daną która nigdy nie nadejdzie. Oczywiście przerwanie cały czas jest wywoływane (co 1 sekundę), ale reszta programu już wisi.

    Jakie macie pomysły na takie problemy? W skrócie problem polega na tym, że wykonując jakiś kod wyskoczy przerwanie, ale po jego powrocie zewnętrzne urządzenie już nie odpowie z powodu przekroczenia czasu, który "zabrał" kod przerwania. Wtedy program wisi na pętli sprawdzającej odpowiedź.

    Mam dwa pomysły.
    Jednym jest nie wykonywanie kodu (czasochłonnego) w przerwaniu, a np ustawienie jakiegoś znacznika i szybki powrót do programu głównego. Oszczędzi to czas, ale i tak upływa ileś tam us na to przerwanie. Minus to sprawdzanie cały czas flagi i ewentualne wykonanie tego co miało być w przerwaniu w zwykłej funkcji, trochę bez sensu w przypadku długich kodów (sprawdzanie w main).

    Inne to zablokowanie przerwań na czas wykonywania tych wrażliwych funkcji czasowych (jak obsługa 1wire). Minus to wstawianie wszędzie blokady (cli()) i zezwolenia (cei()) - kupa roboty przy dużym programie i jeśli funkcja długo czeka to zablokowanie przerwań może powodować przepadnięcie kilku wystąpień przerwania (np zablokowanie przerwania na 2 sekundy powoduje przepadnięcie jednego wykonania przerwania). Do tego - czy jeżeli w czasie blokady przerwań wystąpi jakieś przerwanie to po ich odblokowaniu jest ono wykonywane czy przepada? Co jeśli w czasie blokady wystąpią 2 zgłoszenia przerwania?

    0 3
  • #2 02 Mar 2009 17:29
    Freddie Chopin
    Specjalista - Mikrokontrolery

    rozwiazaniem jest napisanie porzadnego kodu. wyslanie 6 bajtow po uarcie trwa dlugo? chyba z predkoscia 1200bps. pozatym - poza przerwaniem od timera wymyslono cos takiego jak przerwanie od zakonczenia transmisji po UART. tak wlasnie powinienes owy UART obslugiwac, a nie czekac wewnatrz przerwania na costam. przerwanie co 1 sekunde powinno jedynie odpalac taka transmisje, co powinno zajmowac max 20 taktow.

    zasada jest prosta - przerwania maja byc ZAWSZE maxymalnie krotkie. wyjatek stanowia tutaj jedynie przemyslane sytuacje, w ktorych nie ma takiej potrzeby (np w petli glownej i tak nic sie nie dzieje).

    4\/3!!

    0
  • #3 02 Mar 2009 17:57
    Myrek1
    Poziom 23  

    U mnie trwa ok 400us, czyli bardzo dużo jak na 1wire. I przez to wywala się program.

    Czyli zrobić tak, że w przerwaniu od timera wysłać jeden bajt, a w przerwaniu od zakończenia transmisji wrzucić resztę 5) bajtów z rozróżnieniem co zostało wcześniej wysłane, żeby wysłać po kolei te 5 bajtów.

    0
  • #4 02 Mar 2009 18:28
    archanoid
    Poziom 25  

    Witam . Kiedyś pisałem w asemblerze obsługę DS 1990 i była ona rozwiązana z uwzględnieniem przerwania od timera. Działało to w następujący sposób. Jest sobie rejestr statusu DS-a każdy bit sygnalizuje inny stan w trakcie odczytu.Na przykład ustawiony bit 0 oznacza reset_on. bit 1 reset_off i tak po kolei.W przerwaniu jest podprogram który sprawdza rejestr statusu i i wykonuje kolejny etap odczytu lub konwersji. Najdłuższą operacją jest reset DS -a ale można to w jednym przerwaniu zainicjować a w kolejnym zwolnić magistralę i czekać na potwierdzenie obecności DS -a , ustawiając odpowiedni bit statusu. W kolejnym przerwaniu można wysłać komendy a w kolejnym odczytać zawartość DS -a. Mam nadzieję że zbytnio nie zagmatwałem po prostu rejestr czy zmienną status traktujemy jako rejestr przesuwny i przesuwamy jedynkę coraz dalej oznaczając tym samym kolejne etapy odczytu lub konwersji.

    0