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][Eclipse/C] Przerwanie od INT1 i INT0

sevotharte 06 Cze 2011 20:41 3008 12
REKLAMA
  • #1 9583619
    sevotharte
    Poziom 10  
    Witam.

    Mam takie problem. Chcę sobie poćwiczyć zrobienie tzw bramy świetlnej na mikro, z wykorzystaniem INT1 i INT0. Bramy są zewnętrznymi urządzeniami, na nózki Atmegi podaję tylko sygnały logicznej 1 lub 0.

    Mam taką sytuację:
    - przerywam bieg pierwszej bramy, zostaje zliczona osoba
    - jednoczesnie zostaje wylaczone przerwanie drugiego czujnika, na 1sekunde.
    - po sekundzie zostaje wlaczone przerwanie od drugiego czujnika
    - w druga strone jest analogicznie, tylko osoba zostaje odjeta ze zmiennej.

    Realizuje to na przerwaniach: INT0, INT1 i Timerze1. Ale za nic nie mogę dojść co mam źle. Przechodzę przez obydwie bramy, zlicza mnie (2 czujnik nie działa) ale po równej sekundzie zostaje odjeta zmienna i wychodzi na 0. Oto kod:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    natomiast w głównej pętli mam takie cos:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Deklaracja przerwań:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Jaki może być błąd? Ustawione są na zbocze opadające.

    Pozdrawiam
  • REKLAMA
  • REKLAMA
  • #3 9583758
    sevotharte
    Poziom 10  
    tak, bariera jest optyczna. Przerwania włączam, by uchwycić moment przerwania tej bariery, ustawić flagę, dzięki której później w programie zwiększam zmienną ilosc_osob.

    Włączam i wyłączam by rozroznic czy osoba wchodzi czy wychodzi. Jezeli wchodzi to pierwsza bariera dziala, a druga nie dziala przez 1 sekunde. Tak zalozylem. Ale po odliczonym czasie jednej sekundy druga bariera tak jakby zadzialala (odejmuje ilosc osob)
  • #5 9583820
    sevotharte
    Poziom 10  
    nie - bariera jest rozstawiona teraz na powiedzmy około 6 cm od siebie. Wydaje mi się, że jest to problem z timerem, ale wg mojej oceny prawidłowo go zadeklarowałem.

    Dodam, iż kwarc mam 11.0592MHz. Preskaler 256. Przerwanie timera co 1 sekundę.
  • REKLAMA
  • #7 9583890
    sevotharte
    Poziom 10  
    Program jest dość obszerny więc postaram się przedstawić wszystko co jest potrzebne do przeanalizowania. Więc tak:

    PROGRAM GŁÓWNY:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    PRZERWANIA
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    TIMERY


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Dzięki za pomoc!
  • #8 9583902
    janbernat
    Poziom 38  
    Właczasz/ wyłączasz flagi zezwolenia na obsługę przerwań.
    A nie kasujesz flag przerwań- tych w rejestrze GIFR.
    One tam zostają- i jak tylko ponownie zezwolisz na obsługę przerwania- to się wykona, no bo flaga przerwania jest ustawiona.
    Czym innym jest flaga przerwania a czym innym flaga zezwolenia na obsługę przerwania.
    Co zresztą pozwala na obsługę przerwania w pętli głównej bez deklaracji obsługi przerwań.
    No ale sposobów jest mnóstwo.
  • REKLAMA
  • #9 9583975
    sevotharte
    Poziom 10  
    Rzeczywiście :) dzięki janbernat!

    Dla potomnych, ustawiłem tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Poprawnie, czy jeszcze jakoś inaczej to ustawić? czy wystarczy tylko flagi w GIFR włączać/wyłączac?
  • #10 9584127
    janbernat
    Poziom 38  
    Nie analizowałem czasów.
    Sam to zrób.
    Bo jeśli skasujesz flagę przerwania a ustawi się następna- to znowu się włączy.
    O ile pamiętam to te flagi można tylko skasować- ustawić się nie da.
    No i najważniejsze- czy teraz działa?
  • #11 9584455
    dondu
    Moderator na urlopie...
    Moim zdaniem, blokowanie przerwań jest całkowicie zbędne, a wręcz niewłaściwe.
    Możemy sobie wyobrazić sytuację w której ktoś naruszy pierwszą barierę ale nie przejdzie drugiej, bo się rozmyśli - co wtedy? uwzględniłeś to w kodzie?
  • #12 9585057
    sevotharte
    Poziom 10  
    @janbernat
    Teraz moje założenia działają.

    @dondu
    to wtedy zostaje zliczony jako osoba wchodząca do pomieszczenia. Trudno by było to przewidzieć, chyba żeby wykombinować jakąś inną zasadę działania. np.

    wchodzę, timer odlicza 1 sekundę, jak przejdę przez drugą barierę to się zliczy a jak nie to zmienna się nie zmienia.

    Chyba,że ktoś ma inny pomysł to bym prosił o pokazanie waszych koncepcji.
  • #13 9585096
    dondu
    Moderator na urlopie...
    sevotharte napisał:
    ... to wtedy zostaje zliczony jako osoba wchodząca do pomieszczenia.

    :) jeżeli tak jest to po co czekasz na drugą barierę?


    sevotharte napisał:
    Trudno by było to przewidzieć, chyba żeby wykombinować jakąś inną zasadę działania. np.
    wchodzę, timer odlicza 1 sekundę, jak przejdę przez drugą barierę to się zliczy a jak nie to zmienna się nie zmienia.
    Chyba,że ktoś ma inny pomysł to bym prosił o pokazanie waszych koncepcji.

    Dlaczego uważasz, że trudno? Już napisałem - bez blokowania przerwań i dodam, że bez odliczania 1 sek - po co to? A co będzie gdy będzie stał z naruszoną barierą A przez 2sek a potem jednak pójdzie dalej?

    Rozpisz na kartce jakie mogą być przypadki i tyle.

    Po prostu sprawdzasz 4 przypadki:
    1. naruszona bariera A, nastepnie w dowlnym czasie bariera B przy ciągłym naruszeniu bariery A - gość wchodzi do pomieszczenia.

    2. naruszona bariera A, i zwolniona bez naruszenia bariery B - gość wchodził, ale się rozmyślił

    3. naruszona bariera B, nastepnie w dowlnym czasie bariera A przy ciągłym naruszeniu bariery B - gość wychodzi z pomieszczenia.

    4. naruszona bariera B, i zwolniona bez naruszenia bariery A- gość wychodził, ale się rozmyślił

    Oczywiście aby było super poprawnie należałoby jeszcze brać pod uwagę, że:
    - gość naruszył obie bariery ale jednak się cofnął,
    - przeszedł już barierę A i jest jeszcze na barierze B, ale zatrzymał się i wrócił
    Te przypadki także dla każdego z kierunków.

    Ale to żaden problem dla Ciebie i proste do napisania.

    Innymi słowy, stan nienaruszanych obu barier jest jakby resetem całego algorytmu a Twoim zadaniem jest rozpoznawać kolejności włączania i wyłączania dwóch barier, bez sztucznego ograniczania czasem 1 sek.

    Można to rozwiązać dzięki timerowi, który w przerwaniu będzie skanował oba piny.
    Ale można także wykorzystać tryb przerwania przy dowolnym zboczu INT0 i INT1 - Any logical change on INTx generates an interrupt request

    Przynajmniej ja bym tak zrobił.
REKLAMA