Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Atmega328p][c] - Przerwanie zewnętrzne

24 Lis 2016 12:10 1257 28
  • Poziom 4  
    Witam, podłączyłem do portu INT1 przycisk i chciał bym żeby zbocze narastające wywoływało przerwanie, w którym zwiększam licznik o 1. Ustawiłem na MCUCR jedynki dla ISC11 oraz ISC10 co odpowiada wykrywaniu zbocza narastającego, włączyłem przerwanie na INT1 oraz odblokowałem globalnie przerwania, ale niestety licznik inkrementuje się w kółko gdy na port podane jest 0.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    W czym jest problem?
  • Moderator Mikrokontrolery Projektowanie
    Bo użyłeś niewłaściwy rejestr do ustawienia zbocza.
    Patrz rozdział: 17.2.1. External Interrupt Control Register

    W efekcie nadal masz wybrane przerwania na: The low level of INT1 generates an interrupt request.

    Przy okazji pamiętaj o drganiach styków: http://mikrokontrolery.blogspot.com/2011/04/przycisk-drgania-stykow-debouncing.html
  • Poziom 27  
    I ustawiasz DDRD |= (1<<PD3); czyli pin PD3 jako wyjście.
  • Użytkownik usunął konto  
  • Pomocny post
    Poziom 27  
    Piotrus_999 napisał:
    To akurat może być. Słuzy to do progamowego wyzwalania tego przerwania, jak jest taka potrzeba.

    wiem, ale
    lukhol2 napisał:
    podłączyłem do portu INT1 przycisk

    więc to nie ten przypadek :)

    A jak za chwilę będzie chciał włączyć pull-up dla przycisku i weźmiemy pod uwagę, że robi się to tak:
    Cytat:
    If PORTxn is written to '1' when the pin is configured as an input pin, the pull-up resistor is activated.

    to przycisk fajnie będzie działał jako zworka pinu w stanie wysokim do masy ;)
    Nie wiem, czy tego właśnie nie chciał osiągnąć ustawiając PIND zamiast PORTD?
    Niby wpis do PIND nie jest całkiem bez sensu i powoduje przełączenie (toggle) stanu wybranego pinu, ale trochę w dziwnym miejscu by to było robione...
    Cytat:
    Bits 7:0 – PINDn: Port D Input Pins Address [n = 7:0]
    Writing to the pin register provides toggle functionality for IO.
  • Moderator Mikrokontrolery Projektowanie
    Należy dodać jeszcze to:

    Cytat:
    18.2.2. Toggling the Pin
    Writing a '1' to PINxn toggles the value of PORTxn, independent on the value of DDRxn. The SBI
    instruction can be used to toggle one single bit in a port.


    Bez wątpienia natomiast nieprawidłowe jest ustawianie pinu jako wyjście, by podłączyć przycisk.

    Jak masz podłączony ten przycisk, bo mam wrażenie, że do Vcc?
  • Poziom 4  
    Po poprawie program wygląda tak jak w syntaxie. Teraz programowo wszystko z przerwaniem powinno być ok (jeżeli ciągle nie jest, proszę o wskazanie co jest błędne). Licznik nie liczy poprawnie ponieważ ciągle występuje drganie styków, które chciał bym rozwiązać sprzętowo, ale aktualnie nie mam odpowiedniego kondensatora i rezystora. Wiem, że mógł bym rozwiązać to programowo, ale przerwanie zewnętrzne będzie potrzebne mi do kontaktronu, gdzie wygodniej będzie mi zrealizować to sprzętowo. Przypadek z przyciskiem był tylko testowy.
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Reaguję na zbocze opadające ponieważ przycisk podłączony jest do gnd.
  • Pomocny post
    Poziom 27  
    Poczytaj sobie jakiś poradnik o C, np. linkowany przez kol. dondu, bo nie robisz tego, co byś chciał, np.
    lukhol2 napisał:
    DDRD |= ~(1<<PD3); //Ustawienie pinu jako wejście
    nope, powinno być DDRD &= ~(1<<PD3);, bo swoją linijką ustawiasz jako wyjścia wszystkie inne piny, a PD3 zostawiasz nietknięte... Jako że po resecie DDRD=0, to możesz myśleć, że zadziałało, ale to zbieg okoliczności w tym konkretnym przypadku.

    Inna sprawa, że przy inicjalizacji możesz śmiało wpisywać wprost wartości do rejestru, np. DDRD=0 lub PORTD=(1<<PD3) itp. Dopiero potem, gdy rejestr obsługuje coś więcej niż to, co chcesz zmodyfikować, to bawisz się poszczególnymi bitami zachowując wartość pozostałych.
  • Poziom 4  
    krisRaba napisał:
    Poczytaj sobie jakiś poradnik o C, np. linkowany przez kol. dondu, bo nie robisz tego, co byś chciał... np.

    lukhol2 napisał:
    DDRD |= ~(1<<PD3); //Ustawienie pinu jako wejście
    nope, powinno być DDRD &= ~(1<<PD3);, bo swoją linijką ustawiasz jako wyjścia wszystkie inne piny, a PD3 zostawiasz nietknięte... Jako że po resecie DDRD=0, to możesz myśleć, że zadziałało, ale to zbieg okoliczności w tym konkretnym przypadku.


    Mój błąd, język c znam odpowiednio dobrze, ale z mikrokontrolerami dopiero zaczynam, a głównie tutaj używa się takich logicznych kombinacji. Dzięki
  • Moderator Mikrokontrolery Projektowanie
    lukhol2 napisał:
    Licznik nie liczy poprawnie ponieważ ciągle występuje drganie styków, które chciał bym rozwiązać sprzętowo, ale aktualnie nie mam odpowiedniego kondensatora i rezystora. Wiem, że mógł bym rozwiązać to programowo, ale przerwanie zewnętrzne będzie potrzebne mi do kontaktronu, gdzie wygodniej będzie mi zrealizować to sprzętowo.

    Skoro nie masz kondensatora i rezystora, to właśnie ten fakt powinien Ciebie zmobilizować, by rozwiązać ten problem programowo :)

    Jeden ze sposobów:

    Przerwanie może się samo wyłączyć poprzez wyzerowanie bitu INT1 w EIMSK, a jakieś inne przerwanie od timera (na pewno masz i używasz) powinno ponownie włączyć przerwanie INT1 po upływie określonego czasu na przeczekanie drgań.

    Tablicę napis masz za krótką.
  • Specjalista - Mikrokontrolery
    Mniej więcej co 2 tygodnie ktoś tu próbuje obsługiwać przycisk na przerwaniu portu i co dwa tygodnie próbujemy takiemu delikwentowi wybić ten nierozsądny pomysł z głowy. Przeszukaj archiwum. Przycisków NIE obsługuje się przy użyciu przerwań portu, a przy użyciu przerwania timera.
  • Poziom 4  
    BlueDraco napisał:
    Mniej więcej co 2 tygodnie ktoś tu próbuje obsługiwać przycisk na przerwaniu portu i co dwa tygodnie próbujemy takiemu delikwentowi wybić ten nierozsądny pomysł z głowy. Przeszukaj archiwum. Przycisków NIE obsługuje się przy użyciu przerwań portu, a przy użyciu przerwania timera.

    Jak chodzi o mikrokontolery jestem początkujący. Tego typu obsługa była mi potrzebna do przetestowania zasady działania. W układzie, który robię będę używał kontaktronu do zliczania impulsów, a do tego najlepiej chyba będzie wykorzystać właśnie przerwanie zewnętrzne. Niestety nie mam jeszcze kontaktronu ponieważ zamówiłem i ciągle na niego czekam, stąd test na przycisku.
    Dodano po 54 [minuty]:
    Odejdę lekko od przerwań zewnętrznych i zapytam o przerwanie wewnętrzne. Interesuje mnie wykonanie przerwania co 1sec. Z tego co doczytałem w datasheecie Atmega328p ma ustawione defaultowe taktowanie na 8MHz. W związku z czym w main umieściłem coś takiego:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    natomiast przerwanie obsługuję tak jak w przypadku przerwania zewnętrznego z tego tematu, czyli:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    ale niestety program nie działa. Jakieś porady?

    EDIT: Zmieniłem następująco (linie zakomentowane są takie jak wyżej, błędne):
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wynika z tego, że częstotliwość taktowania procka to 1MHz, a nie 8MHz i to rozumiem, ale nie rozumiem czemu musiałem wpisać do TIMSK1 OCIE1A, a nie OCR1A. Wiem też, że liczenie do wartości 3000 nie odpowiada 1 sekundzie, ale tu wystarczy zmienić preskaler i wartość, do której będę liczył.
  • Specjalista - Mikrokontrolery
    Przecież kontraktron też zawiera drgający styk. Nie da się tego podłączyć pod wejście przerwania, a cały kod obsługi styku w przerwaniu timera - to dwie linijki w C.
    Zrozum - to nie ma w ogóle prawa działać w ten sposób.
    Jaka jest spodziewna częstotliwość impulsów z kontaktronu?
  • Poziom 4  
    BlueDraco napisał:
    Przecież kontraktron też zawiera drgający styk. Nie da się tego podłączyć pod wejście przerwania, a cały kod obsługi styku w przerwaniu timera - to dwie linijki w C.
    Zrozum - to nie ma w ogóle prawa działać w ten sposób.
    Jaka jest spodziewna częstotliwość impulsów z kontaktronu?


    Nie bardzo rozumiem czemu nie ma prawa działać w przerwaniu. Maksymalna częstotliwość jakiej będę spodziewał się na kontaktronie to około 18Hz. Drgania styków będę chciał wyeliminować filtrem RC.
  • Poziom 27  
    Przy 18Hz, to MCU zdąży wykryć zbocze, napić się kawy, pójść na spacer do parku, odwiedzić rodzinę itp. nim nadejdzie kolejne zbocze ;) Więc jak BlueDraco radzi, może to być zrobione inaczej i niczego nie zgubisz.
  • Poziom 4  
    krisRaba napisał:
    Przy 18Hz, to MCU zdąży wykryć zbocze, napić się kawy, pójść na spacer do parku, odwiedzić rodzinę itp. nim nadejdzie kolejne zbocze ;) Więc jak BlueDraco radzi, może to być zrobione inaczej i niczego nie zgubisz.

    BlueDraco napisal, ze nie da sie tego zrobić w ten sposob, dlatego nie bardzo rozumiem jego radę :D chyba, ze ma na myśli lepszy sposób.
  • Moderator Mikrokontrolery Projektowanie
    Jeśli urządzenie działa tak jak chce autor, to każdy sposób wykorzystania przerwania zewnętrznego jest prawidłowy.

    W niektórych przypadkach podłączenie przycisku pod pin przerwania zewnętrznego jest niezbędne np. by wybudzić mikrokontroler z trybu Power Down lub Standby.

    Czasami nie ma po prostu innego wyjścia, ze względu specyficzne wykorzystanie wszystkich timerów.
    Faktem natomiast jest, że taka sytuacja zdarza się niezmiernie rzadko i z reguły jakiś timer działa przez cały czas lub jakiś timer jest wolny, więc można je wykorzystać tak jak sugeruje BlueDraco

    Dlatego nie można jednoznacznie twierdzić, że przycisku nie wolno podłączać do pinów przerwań.
    Każdy sposób jest dobry pod warunkiem, że jest skuteczny.
  • Poziom 4  
    dondu napisał:
    Jeśli urządzenie działa tak jak chce autor, to każdy sposób wykorzystania przerwania zewnętrznego jest prawidłowy.

    W niektórych przypadkach podłączenie przycisku pod pin przerwania zewnętrznego jest niezbędne np. by wybudzić mikrokontroler z trybu Power Down lub Standby.

    Czasami nie ma po prostu innego wyjścia, ze względu specyficzne wykorzystanie wszystkich timerów.
    Faktem natomiast jest, że taka sytuacja zdarza się niezmiernie rzadko i z reguły jakiś timer działa przez cały czas lub jakiś timer jest wolny, więc można je wykorzystać tak jak sugeruje BlueDraco

    Dlatego nie można jednoznacznie twierdzić, że przycisku nie wolno podłączać do pinów przerwań.
    Każdy sposób jest dobry pod warunkiem, że jest skuteczny.

    Czyli sugerujesz, ze lepszym rozwiązaniem bylo by po prostu cykliczne odczytywanie impulsów z kontaktronu w przerwaniu wewnętrznym?
  • Poziom 27  
    Hehe, świetny materiał! :) Trochę zaskoczyły mnie mikroswitche, bo widziałem kiedyś materiał, w którym zachowywały się rewelacyjnie. Choć w porównaniu z innymi testowanymi opcjami, to i tak nie jest z nimi źle.
  • Moderator Mikrokontrolery Projektowanie
    Film był w artykule, w który wskazałem Ci w poście #2 ... nie zaglądnąłeś :)

    krisRaba napisał:
    Trochę zaskoczyły mnie mikroswitche, bo widziałem kiedyś materiał, w którym zachowywały się rewelacyjnie.

    Jeśli to film, o którym wiem, to tamten film był "tendencyjny" pokazany pod konkretne wyssane z palca zapotrzebowanie udowadniane przez jego autora.

    krisRaba napisał:
    Choć w porównaniu z innymi testowanymi opcjami, to i tak nie jest z nimi źle.

    Ale czas i każde kliknięcie działa na ich niekorzyść. :)
  • Poziom 27  
    dondu napisał:
    Film był w artykule, w który wskazałem Ci w poście #2 ... nie zaglądnąłeś :)

    Najważniejsze, czy Autor zajrzał :D Ja o drganiach styków wiem i niejedne zwalczyłem, więc może dlatego się nie skusiłem :D Natomiast sam materiał jest fajną ilustracją zjawiska. Na oscyloskopie też to ciekawie wygląda, bo kiedyś badałem czasy ustalania się w interesujących mnie przypadkach.

    dondu napisał:
    Jeśli to film, o którym wiem, to tamten film był "tendencyjny" pokazany pod konkretne wyssane z palca zapotrzebowanie udowadniane przez jego autora.

    Możliwe. Ja już nie pamiętam gdzie to było :)
  • Moderator Mikrokontrolery Projektowanie
    krisRaba napisał:
    dondu napisał:
    Film był w artykule, w który wskazałem Ci w poście #2 ... nie zaglądnąłeś :)

    Najważniejsze, czy Autor zajrzał :D

    Ha, ha, ha, ... ale ze mnie gapa! Pomyliłem Ciebie z autorem tematu. Przepraszam. :lol:
  • Poziom 4  
    dondu napisał:
    Jeśli urządzenie działa tak jak chce autor, to każdy sposób wykorzystania przerwania zewnętrznego jest prawidłowy.

    W niektórych przypadkach podłączenie przycisku pod pin przerwania zewnętrznego jest niezbędne np. by wybudzić mikrokontroler z trybu Power Down lub Standby.

    Czasami nie ma po prostu innego wyjścia, ze względu specyficzne wykorzystanie wszystkich timerów.
    Faktem natomiast jest, że taka sytuacja zdarza się niezmiernie rzadko i z reguły jakiś timer działa przez cały czas lub jakiś timer jest wolny, więc można je wykorzystać tak jak sugeruje BlueDraco

    Dlatego nie można jednoznacznie twierdzić, że przycisku nie wolno podłączać do pinów przerwań.
    Każdy sposób jest dobry pod warunkiem, że jest skuteczny.

    Czyli sugerujesz, ze lepszym rozwiązaniem bylo by po prostu cykliczne odczytywanie impulsów z kontaktronu w przerwaniu wewnętrznym?
  • Poziom 4  
    Mam jeszcze pytanie odnośnie sprzętowej eliminacji drgania styków. Zrobiłem sobie do tego przycisku, który podłączony jest do INT1 i ma wywoływać przerwanie na zbocze narastające filtr RC. Podłączyłem go w ten sposób: [Atmega328p][c] - Przerwanie zewnętrzne i dobrałem wartości rezystora i kondensatora tak jak na schemacie. W dużej mierze wyeliminowałem drgania styków, ale czasem jednak licznik przeskoczy mi o 2, zamiast o 1. Zastanawiam się czy dobranie innych wartości poprawi tą eliminację drgań czy może sposób z filtrem RC nie jest aż tak dobry?
  • Użytkownik usunął konto  
  • Specjalista - Mikrokontrolery
    Fajną grzałkę zrobiłeś i iskrownik przy okazji. O funkcji grzejnika dotychczas nie pisałeś, z kolei kondensator 100 uF spowoduje szybkie upalenie styków.
    Drgania styków jednak łatwiej, taniej i skuteczniej igoruje się programowo.
  • Użytkownik usunął konto