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

Jak zliczać czas stanu niskiego w Atmega16 BASCOM przy przerwaniach?

BOGAD 10 Lut 2007 12:31 2816 8
REKLAMA
  • #1 3551917
    BOGAD
    Poziom 11  
    Posty: 15
    Mam pytanko czy da się zrobić tak aby przerwanie było aktywowane zboczem opadającym i wyłączane narastającym? czy trzeba to zrobić na 2 przerwaniach? bo chodzi mi o zliczanie czasu trwania stanu niskiego i nie wiem dokładnie jak to zrobić.
    Z góry dzięki za pomoc
  • REKLAMA
  • #2 3551956
    ja_dzik
    Poziom 18  
    Posty: 256
    Pomógł: 28
    Ocena: 17
    Mozesz wykorzystac rozkaz Bitwait. Chodzi o to ze jesli wpiszesz:
    
    Bitwait pind.1 , set 
    

    to program zostanie wstrzymane tak długo az na porcie d.1 pojawi sie stan wysoki.
    Czyli najpierw konfigurujesz np przerwanie INT0 tak aby włączało sie przy opadającym zboczu następnie w programie przrwania zliczasz czas np za pomocą któregos z timerów, wpisujesz własnie rozkaz Bitwait który podowuje ze program nie bedzie dalej przechodził dopuki na porcie d.1 nie pojawi sie stan wysoki, ale timer dalej bedzie zliczał czas dopuki nie zostanie on zatrzymany.
  • REKLAMA
  • #3 3551967
    crazy_phisic
    VIP Zasłużony dla elektroda
    Posty: 2244
    Pomógł: 278
    Ocena: 130
    Rejestry konfiguracyjne możesz zmieniać w każdej chwili ;) więc nie ma problemu aby w obsłudze przerwania napisać Config INTx = Rising

    Pozdrawiam
  • REKLAMA
  • Pomocny post
    #4 3552407
    redart
    Poziom 23  
    Posty: 529
    Pomógł: 51
    Ocena: 30
    Najpierw dajesz
    Config INT0=Falling

    Wprowadzasz zmienną opisującą wybrane zbocze wyzwalające przerwanie (Edge_) i w procedurze obsługi tego przerwania:
    If Edge_ =0 Then 
       Start Timer1
       Config INT0=Rising
    Else
       Stop Timer1
       Config INT0=Falling
    End If


    Niektóre AVR'y umożliwiają konfigurację typu
    Config INT0= Change
    Wtedy przerwanie wywoływane będzie po stwierdzeniu dowolnego zbocza sygnału.
  • REKLAMA
  • #5 3554784
    BOGAD
    Poziom 11  
    Posty: 15
    redart napisał:
    Najpierw dajesz
    Config INT0=Falling

    Wprowadzasz zmienną opisującą wybrane zbocze wyzwalające przerwanie (Edge_) i w procedurze obsługi tego przerwania:
    If Edge_ =0 Then 
       Start Timer1
       Config INT0=Rising
    Else
       Stop Timer1
       Config INT0=Falling
    End If


    Niektóre AVR'y umożliwiają konfigurację typu
    Config INT0= Change
    Wtedy przerwanie wywoływane będzie po stwierdzeniu dowolnego zbocza sygnału.


    OK to jeszcze dopytam tak, rozumiem że na początku przerwania zmieniam stan Edge_ na 0, liczy timer i config int0=rising ale co dalej załóżmy że nadejdzie zbocze narastające i co wtedy się dzieje?
  • #6 3557099
    redart
    Poziom 23  
    Posty: 529
    Pomógł: 51
    Ocena: 30
    BOGAD napisał:


    OK to jeszcze dopytam tak, rozumiem że na początku przerwania zmieniam stan Edge_ na 0, liczy timer i config int0=rising ale co dalej załóżmy że nadejdzie zbocze narastające i co wtedy się dzieje?


    No tak, zabrakło jeszcze jednej linijki... sory...
    Powinno być:
    If Edge_ =0 Then 
       Start Timer1
       Config INT0=Rising
    Else
       Stop Timer1
       Config INT0=Falling
    End If
    Toggle Edge
    

    Działa to tak: najpierw masz wejście INT wyzwalane zboczem opadającym, jeśli ono nadejdzie to startuje Timer i zmienia aktywację przerwania na zbocze narastające. Po wyjściu z pętli If/Then zmienia wartość zmiennej Edge_ na przeciwną, sygnalizującą które zbocze jest aktywne (wtedy aktywne jest narastające). Wraca do głównej pętli. Gdy nadejdzie zbocze narastające na we INT to wykonywany jest drugi warunek w procedurze obsługi przerwania: zatrzymany zostaje Timer, następuje ponowna zmiana zbocza aktywującego przerwanie na opadające i na koniec odwrócenie zmiennej Egde_. Coś jeszcze nie jasne?
    Sory za tę linijkę, ale jak się człowiek spieszy...
  • Pomocny post
    #7 3557521
    szymtro
    Poziom 30  
    Posty: 1421
    Pomógł: 101
    Ocena: 59
    Jeżeli już tak to ustaw przerwanie na każdą zmianę i sprawdzaj stan pinu int0.
    będzie szybsze bo nie będzie procedur ustawiania falling/rising:
    config int0=change
    ...
    przerwanie_int0:
    if pind.2=0 then 'opadajace zbocze
    else 'narastajace
    end if
    ...
    return
    Z analizy kodu asm bascoma wynika ze szybciej zadziała oddzielny warunek:
    if pind.2=0 end if
    if pind.2=1 end if
    niż if/else/end if
  • #8 3565762
    BOGAD
    Poziom 11  
    Posty: 15
    OK dziękuję wszystkim za pomoc, rozumiem że Timer będzie liczył czas non stop aż nie nadejdzie zbocze narastające i nie dojdzie do komendy stop timer1? Chodzi mi o to że włączam go w przerwaniu a potem się ono kończy i czy timer wtedy nie zakończy zliczania?
  • #9 3566736
    redart
    Poziom 23  
    Posty: 529
    Pomógł: 51
    Ocena: 30
    Po komendzie Stop Timer1 należy odczytać ilość zliczonych impulsów zegarowych przypisując jakiejś zmiennej (typu Word, np Timer_val) jego wartość:
    Dim Timer_val As Word
    ...
    Timer_val=Timer1

    lub
    Timer_val=Counter1

    a następnie wyzerować rejestry timera, przygotowując go do zliczania od nowa:

Podsumowanie tematu

✨ Dyskusja dotyczy sposobu zliczania czasu trwania stanu niskiego na pinie mikrokontrolera Atmega16 programowanego w BASCOM z wykorzystaniem przerwań. Proponowane rozwiązanie polega na konfiguracji przerwania INT0 początkowo na zbocze opadające (Falling), które uruchamia timer, a następnie dynamicznej zmianie konfiguracji przerwania na zbocze narastające (Rising) w procedurze obsługi przerwania. Po wykryciu zbocza narastającego timer jest zatrzymywany, a konfiguracja przerwania wraca do zbocza opadającego. Zmienna Edge_ służy do przełączania trybu zbocza. Alternatywnie można ustawić przerwanie na wykrywanie każdej zmiany stanu (Change) i w procedurze sprawdzać aktualny stan pinu, co eliminuje konieczność przełączania konfiguracji przerwania i może przyspieszyć reakcję. Timer liczy impulsy zegarowe niezależnie od zakończenia procedury przerwania, a po zatrzymaniu należy odczytać jego wartość do zmiennej i wyzerować licznik, przygotowując go do kolejnego pomiaru. Wskazano także możliwość użycia rozkazu Bitwait do zatrzymania programu do momentu pojawienia się stanu wysokiego na pinie, przy jednoczesnym działaniu timera.
Wygenerowane przez model językowy.
REKLAMA