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

[atmega8][c] przerwanie na zbocze opadające nie reaguje

tata_tasiemka 22 Lut 2012 18:13 2326 13
REKLAMA
  • #1 10583205
    tata_tasiemka
    Poziom 10  
    Witam wszystkich bardzo serdecznie. Chcę zaprogramować uC ATmega8 w taki sposób aby mierzył mi długości sygnałów podawanych na wejście. Oczywiście przy użyciu przerwań. Nie wiem dlaczego program nie reaguje przerwaniem na zboczu opadającym sygnału. Poniżej zamieszczam kod programu. Jeśli mógłbyś zobaczyć i podpowiedzieć w czym tkwi problem byłbym dozgonnie wdzięczny. Tata.

    [code]
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 10583798
    11111olo
    Poziom 42  
    Co wywołuje fizycznie przerwanie?
  • REKLAMA
  • #3 10587691
    tata_tasiemka
    Poziom 10  
    sygnał podany na wejście PD2.
  • REKLAMA
  • #4 10587747
    11111olo
    Poziom 42  
    To że INT0 wywołuje przerwanie to wynika z kodu.
    Pytałem co wywołuje "fizycznie" przerwanie.
  • #5 10587764
    tata_tasiemka
    Poziom 10  
    prąd o napięciu 5V, z tym że nie uzyskuje zamierzonego efektu już na etapie symulacji buttonem w hapsimie.
  • REKLAMA
  • #6 10587777
    11111olo
    Poziom 42  
    Jeśli nie chcesz (lub nie umiesz) tego napisać to niech pozostanie tajemnicą.
    Czuję że coś elektrycznie jest nie tak.
  • #7 10587841
    tata_tasiemka
    Poziom 10  
    ja nie wiem co jest fizycznie źródłem przerwania i wydaje mi się że to nie jest istotne, bo skoro istnieje możliwość zaprogramowania mikrokontrolera tak żeby wywołać przerwanie zboczem narastającym i opadającym też, to zwyczajnie robię to. przerwanie zboczem narastającym działa, a opadającym niestety nie. potrzebuje tego żeby następnie zmierzyć czas trwania sygnału. gotowość do przerwania ustawiam w rejestrze MSUCR na bitach ISC00 i ISC01, oraz INT0 w rejestrze GICR. mimo to nie działa i podejrzewam że czegoś brakuje, stąd zwracam się z prośbą o pomoc.
  • #8 10587866
    11111olo
    Poziom 42  
    Może źle się wyraziłem.
    Wybór stanów narastających i opadających jak realizujesz?
    To ma kolosalne znaczenie bo poprawnie napisany program nie będzie działał jak źle to zrobisz.
  • #9 10587982
    tata_tasiemka
    Poziom 10  
    na początku programu ustawiam bity:

    
    GICR |= 1 << INT0;
    MCUCR |= (1 << ISC00) | (1 << ISC01); //przerwanie zboczem narastającym
    

    aby zezwolić na obsługę przerwań (INT0 w rejestrze GICR) oraz by przerwanie wyzwoliło zbocze narastające sygnału który sie pojawi (ISC00 = 1 i ISC01 = 1 w rejestrze MCUCR).
    następnie w procedurze obsługi przerwania rozpatruje dwie sytuacje, gdy pomiar jeszcze się nie zaczął i druga gdy już się rozpoczął. aby rozróżnić te sytuacje używam zmiennej bool pomiar. przy obsłudze pierwszej sytuacji, tj. gdy pomiar jeszcze się nie rozpoczął w pierwszej kolejności ustawiam bity w rejestrze MCUCR, aby zadeklarować gotowoć mikrokontrolera do obsługi przerwania zboczem obadającym sygnału(czyli ustawiam ISC00 = 0 i ISC01 = 1), a następnie właczam licznik. w kodzie który zamieściłem zamiast tego włączam diody na porcie C. ułatwiłem to żeby nie mieszać do tego ewentualnich problemów jakie mogą wystąpić z timerem. zmieniam też zmienną pomiar żeby przy przerwaniu zboczem opadającym, kiedy sygnał się skończy, obsłużyć przerwanie częścią kodu w else instrukcji warunkowej. tam ustawiam bity w rejestrze tak aby przy kolejnym sygnale zostało wywołane przerwanie zboczem narastającym, dając możliwość zmierzenia długości kolejnego sygnału. zmieniam również zmienną pomiar, a obsłużenie tej części procedury obsługi przerwania sygnalizuje sobie w kodzie wyłączeniem części diód.
  • #10 10587991
    11111olo
    Poziom 42  
    Więcej nie będę pisał i prosił o odpowiedź.
    Odpowiadasz nie na temat.
  • #11 10590888
    _StinG_
    Poziom 14  
    Błąd prawdopodobnie jest tu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Zerujesz bity ISC00 i ISC01 co daje opcję: The low level of INT0 generates an interrupt request,

    Jeśli chcesz wykrywać zbocze opadające to powinieneć użyć konfiguracji:
    ISC01: 1 ISC00: 0 (The falling edge of INT0 generates an interrupt request)

    więc linijka ta poprawnie powinna wyglądać tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #12 10596339
    tata_tasiemka
    Poziom 10  
    Linijka:
    MCUCR &= ~(1 << ISC00) | (1 << ISC01); //przerwanie zboczem opadającym


    ustawia bity ISC01: 1 ISC00: 0, więc wszystko jest OK.

    W programie brakowało zapisu o ustawieniu pinu PD2 jako wejście(DDR &= ~(1<<2); ), oraz ustawienia rezystora podciągającego(PORTD |= 1<<2; )

    Nie jest to dla mnie do końca zrozumiałe ponieważ spotkałem się ze stwierdzeniem że można wywoływać przerwania z zewnątrz na wejściu INT0(PD2) nawet jeśli pin ten jest ustawiony jako wyjściowy.
  • #13 10596737
    alagner
    Poziom 26  
    Jeżeli chcesz wywołać przerwanie software'owo, to ustawiasz pin jako wyjście i odpowiednio machasz portem z poziomu kodu.
  • #14 10597286
    _StinG_
    Poziom 14  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    to nie ustawi Ci ISC01 na 1 (co najwyżej nie zmieni) mój błąd, bo nie zauważyłem, że tu nie ma nawiasów ale tak czy siak, jeśli ISC01 będzie równe 0 to takie pozostanie. Dlaczego? Odpowiedź:
    Jeśli ISC00 = 3 (te wartości są dla przykładu i nie muszą być zgodne z notą katalogową, ale nie w tym rzecz).
    a ISC01 = 2,
    MCUR = 0b11111011
    to równanie powyższe ustali taki wynik:

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


    Wystrzegaj się takich bugów, bo ciężko je potem znaleźć. Jak to ktoś znacznie mądrzejszy ode mnie kiedyś napisał: Lepiej mieć przejrzysty kod niż fajny.
REKLAMA