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.

ATMEGA8 BASCOM nie działa poprawnie przerwanie INT0

knmp 19 Lut 2010 20:06 4547 7
  • #1 19 Lut 2010 20:06
    knmp
    Poziom 26  

    Witam

    Zasiadłem do BASCOMa AVR i poczyniłem zawiły ale zadowalajacy (jak na to srodowisko) soft dla atmega8, wszystko byloby ok gdyby nie mały problem z obsługą przerwania... mianowicie, na jedno z wejść tj. INT0 podaje przebieg prostokątny, okres 20ms, w aplikacji wymagane jest aby w chwili gdy wystąpi zbocze opadające owego przebiegu (dopiero od pewnego momentu w programie, nie wczesniej ! ) nastąpi przerwanie i skok do podprogramu który juz tam precyzyjnie czasowo od chwili owego zbocza opadajacego wykona operacje itd... idela ogolnie jest taka

    na początku definiuje

    Code:
    Config Int0 = Falling                                      
    
    On Int0 prog

    Do

    tu na poczatku dla pewnosci wpisuje:

    Disable Interrupts
    Disable Int0

    tak by na pewno nie zadziałało za wczesnie przerwanie

    następnie w odp miejscu programu  tam od kiedy miałoby byc przerwanie aktywne podaje:

    Enable Interrupts
    Enable Int0

    i program od tej chwili skacze na przerwanie do

    prog:
    ......
    .....

    Disable Interrupts          'tu probuję ze wszelką cenę wyłączyć obsługę przerwan
    Disable Int0

    return

    i klapa, z jakichs powodów pomimo disable program wraca planowo do paczątku calego programu tam gdzie jest Do i jest czuły na przerwania ale ich nie wykonuje, tak jakby obserwowal nadal wejscie INT0 i wpisywał sobie w rejest ze było zbocze i gdy tylko podam

    Enable Interrupts
    Enable Int0


    to od razu następuje przejscie do prog: tak jakby czekał z zaległym przerwaniem

    a mi zależy na tym, aby dopiero od odpowiedniego momentu całego programu gdy podam włacz przerwania to wtedy zaczał obserwowac INT0 i w chwili gdy dopiero wystąpi to zbocze to przeszedł do prog:

    co robie zle jak to rozwiązac ?

    inventco.eu - pierwsza sprawa regulamin p.11.1, druga sprawa proszę używać znaczników CODE, trzecia sprawa proszę poprawić pisownię regulamin p.15.

    0 7
  • #2 19 Lut 2010 20:44
    xury
    Poziom 39  

    Prawdę mówiąc nie wiem czemu tak się dzieje, ale mam pomysł.
    Np. stawiać flagę w odpowiednim miejscu od kiedy ma reagować na zbocze, a w podprogramie sprawdzać na samym początku czy ta flaga jest ustawiona.

    0
  • #3 19 Lut 2010 20:56
    janbernat
    Poziom 38  

    Bo czym innym jest zezwolenie na obsługę przerwania czyli ustawienie odpowiedniego bitu w rejestrze GICR - czyli enable INTx
    a czym innym skasowanie odpowiedniego bitu w rejestrze GIFR- bitu żądania obsługi przerwania.
    Kasuje się ten bit przez wpisanie 1.

    0
  • Pomocny post
    #4 19 Lut 2010 21:03
    M. S.
    Poziom 34  

    Gdy procesor jest w trakcie wykonywania procedury przerwania, następne przerwanie nie będzie przyjęte, gdyż procesor (nie kompilator!) zeruję flagę globalnego zezwolenia na przerwania. Tak samo flaga bieżącego przerwania (tego, którego procedura obsługi jest wykonywana) zostaje automatycznie wyzerowana. Po zakończeniu przerwania flaga globalnego zezwolenia jest na powrót ustawiana i procesor może przyjąć następne przerwanie.

    tyle help.

    Wyłączenie przerwania w podprogramie obsługi przerwania nic nie da bo w wyniku wykonania Return (asm reti) przerwania uaktywniają się znowu. Trzeba zmusić kompilator aby wstawił tam ret.

    Sposób zawarty jest w helpie:

    Code:
    Enable Interrupts
    

    Enable Int0                'włączenie przerwania

    On Int0 Label2 Nosave      'nastąpi skok do Label2 gdy wystąpi przerwanie

    Do                         'nieskończona pętla

    Loop

    End

    Label2:

     Dim a As Byte

     If a > 1 Then

       Return                  'zastąpione będzie przez RET, gdyż

                               'jest powiązanie z instrukcja IF

     End if

     Return                    'zostanie przetłumaczone na RETI, gdyż

                               'jest to pierwsza instrukcja RETURN

     Return                    'zostanie przetłumaczone na RET, gdyż

                               'jest to następna instrukcja RETURN


    Wynika z tego, że Return powinien być wygenerowany przez IF

    To co napisałem wynika z analizy helpa. Nie sprawdzałem tego w naturze.

    P. S. Kompilator przyjmuje też asemblerowskie RET zamiast Bascomowe Return na zakończeniu podprogramu obsługi przerwania.

    0
  • Pomocny post
    #5 19 Lut 2010 21:12
    janbernat
    Poziom 38  

    To zamiast kombinować z ret i reti wustarczy wpisać w odpowiednim miejscu:
    set gifr.intf0 lub 1.

    0
  • #6 19 Lut 2010 21:25
    M. S.
    Poziom 34  

    Cytat:
    wpisać w odpowiednim miejscu


    A w które miejsce programu nastąpi powrót z podprogramu obsługi przerwania?

    Ok. Trzeba by zmienić rejestr w programie obsługi przerwania.

    0
  • #7 19 Lut 2010 21:29
    knmp
    Poziom 26  

    Dzięki za pomoc, tak znam opis z helpa... ale chyba przeczytałem bez zrozumienia, jasne return ustawia ponownie flage gdy wychodzi z procedury przerwaniowej... ustawiłem GIFR = &B11000000 przed enablami i działa... chyba :)

    Dzięki za pomoc :)

    0
  • #8 19 Lut 2010 21:54
    janbernat
    Poziom 38  

    Cytat:

    A w które miejsce programu nastąpi powrót z podprogramu obsługi przerwania?

    A co ma reti do skasowania flagi żądania przerwania?

    Dodano po 19 [minuty]:

    I pamiętaj że kasujesz w ten sposób flagi obu przerwań.
    W jakimś innym miejscu programu może to być niedobre.
    Dla INT0 wpisz GIFR = &B01000000

    0