logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMEGA32][BASCOM] - Przerwania zagnieżdżone - LCD razem z INT0

glu80 11 Kwi 2013 14:29 2616 7
REKLAMA
  • #1 12185507
    glu80
    Poziom 2  
    Witam forumowiczów,
    Natknąłem się na pewien problem, z którym nie wiem jak sobie poradzić. Sprawa dotyczy nieprawidłowej obsługi przerwania INT0 podczas wykonywania komend sterujących wyświetlaczem LCD.

    Do Atmega32 podłączone są:
    - standardowy wyświetlacz LCD,
    - źródło impulsów (dokładniej jest to liniał cyfrowy),
    - przyciski.
    Impulsy wprowadzone na pin INT0 mają wywoływać procedurę odczytu stanu z dwóch innych wejść, wykonywana jest prosta operacja (zliczanie kroków w przód lub w tył) a wynik wyświetlany na LCD.

    Jest to programowo zrealizowane w oparciu o dwa osobne przerwania i pętlę:
    1. przerwanie INT0, wywoływana jest procedura odczytu stanu na wejściach i odpowiednio zwiększany lub zmniejszany jest wynik. Impulsy pojawiają się dosyć gęsto, nawet co około 20 us (mikrosekund), ale przeważnie odstępy są większe. Czas wykonywania podprogramu obsługi tego przerwania zajmuje 250 cykli zegara, co daje jakieś 15us przy zegarze 16MHz.

    2. przerwanie TIMER0, użyte jest do odświeżania wyświetlacza. Przerwanie wyskakuje co 16ms, ale tylko co 12-te wywołanie jest odświeżany LCD, czyli mniej wiecej 5x na sekundę. Zawartość wyświetlacza jest konstruowana "na żywo" na podstawie aktualnej wartości zmiennych.

    3. Pętla główna, gdzie obsługiwane są tylko przyciski.


    PROBLEM polega na tym, że część impulsów które trzeba zliczać jest gubiona. Przy odświeżaniu wyświetlacza 5x na sekundę gubi się około 20% impulsów, bez względu na częstotliwość impulsów wyzwalających INT0 (przy założeniu, że nie są krótsze od pewnej granicznej wartości).

    Nie jest to na pewno spowodowane zbyt małymi odstępami pomiędzy wywołaniami INT0. Można to łatwo sprawdzić, co też zrobiłem na dwa sposoby:
    - wyłączam przerwanie TIMER0, natomiast wyświetlacz odświeżam przyciskiem, otrzymuję wynik dokładny, czyli wszystkie impulsy są zliczane
    - spowalniam odświeżanie na przykład do 1x na sekundę albo jeszcze wolniej, w efekcie gubionych jest odpowiednio mniej impulsów.


    Wydaje mi się, że podczas wykonywania komend obsługujących LCD (Locate, Lcd) dzieje się jedna z dwóch rzeczy:
    a) przerwania zewnętrzne są wyłączane (nie są obsługiwane przerwania, które są zagnieżdżone jedne w drugich),
    b) brakuje miejsca na zapisanie stanu programu, zapełnia się jakiś stos albo coś takiego (?)
    Tak ma być czy robię coś źle? Jakieś pomysły o co może chodzić i jak podejść do problemu?
  • REKLAMA
  • REKLAMA
  • Pomocny post
    #3 12185709
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #4 12185909
    BlueDraco
    Specjalista - Mikrokontrolery
    Masz błąd w samej koncepcji. Przyciski obsługuj w przerwaniu timera, a LCD w pętli głównej. Nie możesz czekać na LCD w przerwaniu, a testowanie przycisków bez bazy czasu to nieporozumienie.
  • REKLAMA
  • #5 12188308
    glu80
    Poziom 2  
    Na wstępie dziękuję za zainteresowanie moim problemem.

    dondu
    Nie da się tak. Być może nie napisałem tego precyzyjnie, w każdym razie impulsy które wchodzą na INT0 są tylko informacją, że wystąpił krok w prawo lub w lewo. W tym momencie analizując stan dwóch innych wejść (aktualny i sprzed zmiany) trzeba ustalić czy pomiar ma być zwiększony czy zmniejszony o krok.

    emarcus
    LCD obsługuję tak:
    Dim Droga As Long
    Dim Tmp As String * 6
    Dim Tymcz As Single

    Config Timer0 = Timer , Prescale = 1024
    On Timer0 Przerw_wyswietlacz
    ...
    Przerw_wyswietlacz:
       Pomocn_wysw = Pomocn_wysw + 1
       If Pomocn_wysw > 12 Then
          Pomocn_wysw = 0
          Locate 1 , 1
          Tymcz = Droga / 1000
          Tmp = Fusing(tymcz , " ##.&&&")
          Lcd Tmp ; "  "
    Return
    


    Jeśli jest tak jak piszesz:
    Cytat:
    Normalnie, podczas obsługi przerwania wszystkie ewentualnie występujące przerwania są 'zawieszone' do czasu jej ukończenia (Return) i wtedy są zwyczajnie pomijane (gubione).

    to wszystko byłoby jasne... Spróbuję zrobić tak jak sugerujecie, w przerwaniu ustawiana będzie tylko flaga dla LCD. Zobaczę i dam znać.
  • #6 12189515
    Konto nie istnieje
    Poziom 1  
  • #7 12189695
    SylwekK
    Poziom 32  
    Kurcze, taka obsługa LCD w przerwaniu to wg mnie marnotrawstwo przerwania. Przecież to w pętli głównej powinno być. Tak się nie powinno robić. Komendy wyświetlacza są czasochłonne i jak Ci to w krew wejdzie to się zaplątasz w końcu.
  • #8 12305217
    glu80
    Poziom 2  
    Dzięki kolego emarcus za trafną sugestię. Zmiana koncepcyjna i jest OK. Odpisuję późno bo czasu jakoś było brak...

    Poprawny kod, być może przyda się w przyszłości komuś kto będzie miał podobny problem:


    Kod: text
    Zaloguj się, aby zobaczyć kod
REKLAMA