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

[C] Opóźnienie przerwania INT1 w Atmega328 - jak to zrobić programowo?

Modecom601 27 Mar 2012 23:38 5081 15
REKLAMA
  • #1 10727598
    Modecom601
    Poziom 13  
    Posty: 136
    Ocena: 18
    Witam serdecznie!
    Przejdę od razu do sedna. Napisałem program do megi328, z przerwaniem INT1, odpowiednio poustawiałem rejestry, uruchomiłem globalną obsługę przerwań sei(), i niestety atmega po podłączeniu zasilania od razu wykonuje przerwanie, mimo, iż switch nie został wciśnięty, wiem, że tak się dzieje, ponieważ w przerwaniu dla przykładu zapalam diodę. Czy istnieje programowa możliwość opóźnienia działania zewnętrznego przerwania? Próbowałem jakieś małe opóźnienie rzędu 10ms po deklaracji portów, nic to nie dało. Przerwanie wykonuje się bez różnicy, czy przerwanie ma być wykonane na zboczu narastającym, czy opadającym. Na pinie PD3 ustawiam w definicji portów stan logiczny '1', wydaje mi się, że ustawienie tej jedynki wykonuje się "później" niż przerwanie, bo przerwanie to priorytet uC dobrze mówię??

    Zagwostkę rozwiązałem w sposób inny, PD3 podciągnałem do 5V rezystorem 1K, by od razu ustawić na PD3 '1' - wtedy przerwanie nie wykonuje się samoistnie po włączeniu zasilania.

    Czy istnieje programowy sposób zapisu w języku C przerwania tak, by nie wywoływał się po włączeniu zasilania? Oszczędziłbym na płytce 1k rezystor. Jestem w 99% przekonany, że istnieje odpowiedź na moje pytanie, lecz nie znam na nie odpowiedzi - stąd temat w dziale początkujący z wiadomych przyczyn :)

    Zamieszczam fragment testowego programu
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Proszę o pomoc

    Pozdrawiam
  • REKLAMA
  • Pomocny post
    #2 10727624
    Zocha24
    Poziom 21  
    Posty: 386
    Pomógł: 44
    Ocena: 32
    przed odblokowanie przerwań daj _delay_ms(200);
  • Pomocny post
    #3 10727634
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    Zanim odblokujesz przerwania za pomocą sei(), w rejestrze EIFR wykasuj flagę INTF1
    Cytat:
    INTF1: External Interrupt Flag 1
    When an edge or logic change on the INT1 pin triggers an interrupt request, INTF1 becomes set
    (one). If the I-bit in SREG and the INT1 bit in EIMSK are set (one), the MCU will jump to the corresponding
    Interrupt Vector. The flag is cleared when the interrupt routine is executed.
    Alternatively, the flag can be cleared by writing a logical one to it. This flag is always cleared
    when INT1 is configured as a level interrupt.


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • Pomocny post
    #4 10727650
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    Ale nadal pozostaje pytanie: Dlaczego flaga INTF1 jest ustawiona, skoro po resecie powinna być 0?
    Skoro pull-up wewnętrzny nie daje właściwego rezultatu, a rezystor 1k tak, to czy nie masz czasem jakichś zakłóceń na płytce - zasilanie itp. prawidłowe?
  • #5 10727673
    Modecom601
    Poziom 13  
    Posty: 136
    Ocena: 18
    Zocha24
    Przed sei(); wpisywałem nawet _delay_ms(1000); - bez skutku.

    michalko12
    widzę, że przeoczyłem to w nocie, zastosuję to jutro i dam znać.


    dondu
    jeśli Ty nie wiesz, ja tym bardziej :)
    EDIT: płytka testowa to ZL2AVR ze wszystkimi filtrami itp. - chyba to wykluczyć powinienem.
    Zasilanie usb z komputera, wydaje mi się, że po prostu to jest chyba wina tego priorytetu wykonania się przerwania, ale to ja Was o to pytam. Jak widzicie w kodzie podciągneicie PD3 następuje zaraz po ustawieniu DDRD.
  • Pomocny post
    #6 10727676
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    Modecom601 napisał:
    dondu
    jeśli Ty nie wiesz, ja tym bardziej :)

    To było pytanie do michalko12 :)

    Modecom601 napisał:
    michalko12
    widzę, że przeoczyłem to w nocie, zastosuję to jutro i dam znać.
    Wykasować flage czyli ustawić bit na 0, a w syntax wrzucasz ustawienie bitu, pomyłka rozumiem?

    Nie i michalko12 zacytował Ci wytłuszczając i na czerwono odpowiedni fragment datasheet.
    Więcej znajdziesz tutaj: AVR: Czyhające pułapki
  • Pomocny post
    #7 10727685
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    Modecom601 napisał:

    Wykasować flage czyli ustawić bit na 0, a w syntax wrzucasz ustawienie bitu, pomyłka rozumiem?....


    Przeczytaj to co masz w cytacie z noty PDF na czerwono - przecież jak byk podkreślone, że kasowanie bitu poprzez wpisanie wartości 1 - a ty się pytasz czy to pomyłka w kodzie.
  • Pomocny post
    #8 10727691
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    Modecom601 napisał:
    Wykasować flage czyli ustawić bit na 0, a w syntax wrzucasz ustawienie bitu, pomyłka rozumiem?

    Nie, to nie jest nie pomyłka!
    Przeczytaj co jest pogrubione i zaznaczone na czerwono w cytacie.
  • #9 10727693
    Modecom601
    Poziom 13  
    Posty: 136
    Ocena: 18
    "Flaga zostaje wyzerowana (Wyczyszczona) poprzez wpisanie logicznej jedynki" - mój błąd, nie doczytałem. Wydaje się to być prostym rozwiązaniem, jutro zastosuję i dam znać.


    dondu
    chyba najczęściej z czytelników przeglądam Twoje poradniki, znam ten temat :)

    Bardzo dziękuję Wszystkim za pomoc.
  • REKLAMA
  • Pomocny post
    #10 10727701
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    :D
    Ale nadal mnie nurtuje dlaczego przy takim programie i włączonym wewnętrznym pull-up generuje Ci się przerwanie, pomimo stanu wysokiego na wejściu INT1. Co tam masz podłączone?
  • Pomocny post
    #11 10727713
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    dondu napisał:
    Ale nadal pozostaje pytanie: Dlaczego flaga INTF1 jest ustawiona, skoro po resecie powinna być 0?



    Do tego momentu wejście sobie pływa i logika od wykrywania zbocz może już je rejestrować.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


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

    następuje przełączenie przerwania na inny układ logiczny. Możemy teraz domniemać czy przypadkiem INTF1 nie jest po prostu przełączany z masy na ten układ logiczny, który już wcześniej zarejestrował te zmiany.
  • #12 10727714
    Modecom601
    Poziom 13  
    Posty: 136
    Ocena: 18
    zwykły switch podłączony do masy. coś może z tą nadrzędnością przerwania, nie wiem, ja tutaj jestem początkujący :)

    Nie mogłem tego zostawić na jutro, włączyłem laptop, dopisałem i... DZIAŁA! :)
    Nauczka, by czytać dokładniej DataSheety i nie ustawiać się na przegranej pozycji.

    Bardzo dziękuję za pomoc wszystkim!
    Pozdrawiam i życzę dobrej nocy
  • #13 10727728
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    michalko12 napisał:
    Do tego momentu wejście sobie pływa i logika od wykrywania zbocz może już je rejestrować ...... Możemy teraz domniemać czy przypadkiem INTF1 nie jest po prostu przełączany z masy na ten układ logiczny, który już wcześniej zarejestrował te zmiany.

    No tak, ja założyłem, że INTF1 nie może być ustawione, gdy nie ma włączonych przerwań z INT1, czyli nie jest ustawiona flaga INT1.
    A tak nie jest, czyli flaga INTF1 ustawia się niezależnie od tego, czy jest zezwolenie na fladze INT1.
  • #14 10727735
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    heh :) bo to nie przerwanie ustawia flagi, tylko wręcz przeciwnie.
  • #15 10727743
    michalko12
    Specjalista - Mikrokontrolery
    Posty: 3394
    Pomógł: 462
    Ocena: 321
    dondu napisał:
    czyli flaga INTF1 ustawia się niezależnie od tego, czy jest zezwolenie na fladze INT1.


    To jest standard. Zawsze możesz programowo sprawdzać czy dane zdarzenie miało miejsce bez wywoływania sprzętowego przerwania. Są też inne rozwiązania gdzie są dodatkowe flagi za rejestrem maskującym.
  • REKLAMA

Podsumowanie tematu

✨ Użytkownik napotkał problem z niepożądanym wywoływaniem przerwania INT1 w mikrokontrolerze Atmega328 po włączeniu zasilania, mimo że przycisk nie był wciśnięty. Po kilku próbach, w tym opóźnieniu przed aktywacją przerwań, użytkownik rozwiązał problem, podciągając pin PD3 do 5V za pomocą rezystora 1K, co zapobiegło samoczynnemu wywoływaniu przerwania. W dyskusji poruszono również kwestie związane z kasowaniem flagi INTF1 oraz wpływem zakłóceń na płytce. Użytkownicy zasugerowali, aby przed włączeniem przerwań wyczyścić flagę INTF1 oraz zwrócić uwagę na poprawne ustawienia rejestrów.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA