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

Attiny2313, przerwania zewnętrzne

boohoo 18 Lut 2009 21:26 3606 23
  • #1 6170569
    boohoo
    Poziom 12  
    Witam,

    Mam problem z obsługą przerwań zewnętrznych uC Attiny2313. Do pinów INT0 i INT1 mam podpięte przyciski i za ich pomocą chciałbym załączać diody LED. Wykorzystuję generator wewnętrzny. Napisałem program, ale w ogóle nie reaguje na przyciski. Oto on:
    
    #include <avr\io.h>
    #include <avr\delay.h>
    #include <avr\signal.h>
    #include <avr\interrupt.h>
    
    
    #define D1 0
    #define D2 1
    #define D3 1
    #define BUZZ 0
    
    #define TSOP1 5
    #define SW1 3
    #define SW2 2
    #define PULLUP_ON 0x2C // włączenie pullup dla wejść
    
    int main(void)
    {
    DDRA=(1<<D1 | 1<<D2);
    DDRD=(1<<D3 | 1<<BUZZ);
    PORTD=PULLUP_ON; 
    
    GIMSK = _BV(INT0)|_BV(INT1);
                            //włącz obsługę przerwań Int0 i Int1
    MCUCR = _BV(ISC01)|_BV(ISC11);
                            // włącz generowanie przerwań przez
                            // opadające zbocze na Int0 i Int1
    
    sei();                // włącz obsługę przerwań
    
    
    while(1);
    
    return 0;
    }
    
    /////////////////////////////////////////////////
    
    SIGNAL (SIG_INTERRUPT0) 
    {
      PORTA = 0x0;         // zgaś diode D1
    }
    
    SIGNAL (SIG_INTERRUPT1) 
    {
      PORTA = 0x1;         // zapal diode D1
    }
    


    Bardzo prosiłbym o pomoc, naprowadzenie, co jest nie tak.
    Dołączam także schemat układu:
    Attiny2313, przerwania zewnętrzne

    Pozdrawiam
  • #2 6171163
    mirekk36
    Poziom 42  
    Witam,

    wg mnie, choć już dawno nie pisałem w C i trochę się pozapominało ale:

    1. Gdzie masz ustawienie portów pinów INT1 oraz INT0 jako wejściowe ??? bo jakoś tego nie widzę

    2. co to za zapis?
    DDRA=(1<<D1 | 1<<D2); 


    jak już to chyba powinno być:

    DDRA |= ( (1<<D1) | (1<<D2) );
    czyli ustawienie tych bitów na wartość 1

    a jeśli chcesz ustawić na wartość 0 to powinno być:
    DDRA &= ~( (1<<D1) | (1<<D2) ); 


    ... przypomnę że pin INT1 to PD3 natomiast INT0 to PD2

    tak więc masz troszkę poplątane z pomieszanym albo za mało komentarzy
  • #3 6171206
    Freddie Chopin
    Specjalista - Mikrokontrolery
    pudlo again [;

    D1 i D2 to diody (komentarze w przerwaniu). rejestry DDRx maja domyslnie wartosc oznaczajaca wejscia, wiec nie trzeba koniecznie wpisywac tam zer. z tego samego powodu nie jest konieczne stosowanie operatora |= - skoro wiadomo ze reszta elementow tak czy siak byla zerem i ma byc zerem.

    zapis typu
    REJESTR = (1<<x | 1<<y);
    jest brzydki, ale prawidlowy - priorytet operatora << jest wielokrotnie wyzszy niz operacji bitowej |.

    4\/3!!
  • #4 6171271
    mirekk36
    Poziom 42  
    Freddie Chopin -> no tak tych diod D1 i D2 to nie dostrzegłem ;)

    a odnośnie wiedzy n/t pisania w ten sposób
    REJESTR = (1<<x | 1<<y);

    to oczywiście nie miałem pojęcia a ponieważ jak wiesz od niedawna zaczyna przygodę (gdy mam czas) z językiem C - to wolę trzymać się jakby tych "ładnych" zapisów a nie "brzydkich" - bo sam chyba przyznasz, że i kod a szczególnie większy kod staje się od razu bardziej przejrzysty i czytelny

    swoją drogą to właśnie dzisiaj zakupiłem sobie książeczkę "Mikrokontrolery AVR programowanie w języku C" więc mam nadzieję, że będzie tam więcej jak dla mnie n/t tych różnych jeszcze mało znanych mi niuansów, priorytetów operatorów itp

    Dodano po 10 [minuty]:

    a swoją drogą, takie ustawienie w kodzie żeby pin np klawisza był wejściem też wiele nie kosztuje kodu i pamięci a jaśniej się robi

    no i w związku z tym, dalej zgadując co jest nie tak w tym kodzie że diodki się nie zapalają w tych przerwaniach - to chyba warto byłoby jednak podciągnąć Pullupy ? chyba że ten mega-tajemniczy zapis :

    #define PULLUP_ON 0x2C // włączenie pullup dla wejść 
    to robi ?

    ale czyż nie ładniej i przejrzyściej byłoby gdyby to napisać np tak:

    DDRD &= ~( (1<<SW1) | (1<<SW2) ); //wejścia dla klawiszy
    PORTD |= ( (1<<SW1) | (1<<SW2) ); pullupy dla klawiszy


    zamiast stosowania #define tylko po to żeby sobie w kodzie napisać takiego dziwoląga :

    PORTD=PULLUP_ON; 


    podczas gdy pod tajemniczym PULLUP_ON mieści się jeszcze bardziej tajemniczy zapis 0x2C . Oczywiście wiem o co chodzi w takim zapisie ale chyba lepiej tworzyć kod bardziej przejrzysty niż go zamydlać (to oczywiście moje subiektywne zdanie)
  • #5 6171379
    boohoo
    Poziom 12  
    Ten dziwoląg, w rzeczy samej, podciąga pullupy :P Wybaczcie być może nieco enigmatyczny miejscami kod, ale też stosunkowo niedawno zacząłem przygodę z programowaniem i elektroniką w ogóle. Poprawię się na przyszłość :)

    Co do źródła błędów, to podejrzewam linijki:
    GIMSK = _BV(INT0)|_BV(INT1);
                            //włącz obsługę przerwań Int0 i Int1
    MCUCR = _BV(ISC01)|_BV(ISC11);
                            // włącz generowanie przerwań przez
                            // opadające zbocze na Int0 i Int1
    

    Nie ukrywam, że wzorowałem się tu na przykładzie, znalezionym w jakimś internetowym kursie.

    Dzięki za odpowiedzi :)
  • #6 6171432
    Dr_DEAD
    Poziom 28  
    Nie reaguje to znaczy że ani nie zapala ani nie gasi diody?
    To pewnie błąd na płytce, jeżeli sprawdziłeś programowo że diody świecą to w takim razie odwrotnie wlutowałeś przyciski i piny INT0, INT1 są cały czas na masie.
  • #7 6171496
    dawid512
    Poziom 32  
    Można by również pokusić się o stosowanie ISR zamiast SIGNAL.
  • #8 6171498
    boohoo
    Poziom 12  
    Kurczę, to raczej też nie to, przyciski na pewno dobrze wlutowane, bo napisałem kilka programów z ich wykorzystaniem, tyle że bez obsługi przerwań i działało bez zarzutu. Gdy jednak wrzucam ten program, przyciski poprawnie działają (po wciśnięciu stan niski na pinie), jednak na pinach wyjść nie pojawia się żadne napięcie.
  • #9 6171509
    dawid512
    Poziom 32  
    Zobacz co się stanie gdy zamiast opadającego zbocza wybierzesz stan niski.
  • #10 6171545
    boohoo
    Poziom 12  
    Wypróbuję jutro ten pomysł z niskim stanem, nie wiem, może impuls jest krótszy od okresu zegara, przez co zgłoszenie przerwania nie jest przyjmowane.

    Nie bawiłem się z fusebitami, wg dokumentacji domyślnie wykorzystywany jest wewnętrzny zegar taktowany z f=1MHz. Nie wiem, czy może to mieć jakiś wpływ. Poza tym, wyczytałem przed chwilą w dokumentacji "Note that recognition of falling or rising edge interrupts on INT0 and INT1 requires the presence of an I/O clock". Niestety moja wiedza z uC jest jeszcze zbyt mała, żeby zinterpretować tą informację względem mojego problemu.

    Dodano po 26 [minuty]:

    Jeszcze jedno, przy kompilacji nie wyrzuca błędów, jednak znalazłem 2 ostrzeżenia o treści:
    Migacz_przerwania.c:37: warning: `SIG_INTERRUPT0' appears to be a misspelled signal handler
    Migacz_przerwania.c:42: warning: `SIG_INTERRUPT1' appears to be a misspelled signal handler
  • #12 6172411
    Grzybens
    Poziom 13  
    boohoo napisał:

    Jeszcze jedno, przy kompilacji nie wyrzuca błędów, jednak znalazłem 2 ostrzeżenia o treści:
    Migacz_przerwania.c:37: warning: `SIG_INTERRUPT0' appears to be a misspelled signal handler
    Migacz_przerwania.c:42: warning: `SIG_INTERRUPT1' appears to be a misspelled signal handler


    Masz błędnie nazwane uchwyty do obsługi przerwania, program w ogóle nie wchodzi w procedurę obsługi przerwania. Będzie to świetnie widać w momencie symulacji działania programu. Sprawdź jak powinno się prawidłowo nazywać uchwyty do obsługi przerwań dla ATtinny 2313.

    Pozdrawiam
  • #14 6172502
    Grzybens
    Poziom 13  
    Dokładnie takie samo ostrzeżenie dostawałem od kompilatora w momencie gdy popełniłem "literówkę" w nazwie przerwania.
  • #16 6173540
    boohoo
    Poziom 12  
    Eh... chyba mnie krew nagła zaleje :P
    Więc tak:
    - wypróbowałem wszystkie możliwości ustawiania rejestru MCUCR, niestety dla wszystkich przypadków układ zachowywał się tak samo - nie działał
    - w makefile'u mam wpisane MCU = attiny2313 (dla MCU = ATtiny2313, program się w ogóle nie kompiluje), oraz częstotliwość procesora F_CPU = 1000000
    - programy nie wykorzystujące przerwań działają prawidłowo, przetestowałem wszystkie piny I/O i są Ok

    Wieczorem zainstaluję AVR Studio i przetestuję, może wtedy coś się rozjaśni...

    Hm... Znacie może inne nazwy uchwytów do obsługi przerwań? Byłbym wdzięczny za podanie :)

    Dzięki wszystkim za odpowiedzi i zainteresowanie tematem :)
  • #17 6173627
    Freddie Chopin
    Specjalista - Mikrokontrolery
    boohoo napisał:

    - w makefile'u mam wpisane MCU = attiny2313 (dla MCU = ATtiny2313, program się w ogóle nie kompiluje), oraz częstotliwość procesora F_CPU = 1000000

    a powinienes miec wpisane "-mmcu=attiny2313 -DF_CPU=1000000UL" przy wywolaniach kompilatora.

    Cytat:

    Hm... Znacie może inne nazwy uchwytów do obsługi przerwań? Byłbym wdzięczny za podanie :)


    uchwytow przerwan? to sa po prostu nazwy wektorow, a nie zadne uchwyty...

    gdyby tak poczytac dokumentacje do biblioteki ktora sie wykorzystuje (avr-libc), ktora calkiem przypadkiem dolaczona jest do WinAVR, to nie byloby takich pytan...

    4\/3!!
  • Pomocny post
    #18 6173684
    mirekk36
    Poziom 42  
    boohoo -> przecież jeśli masz AVR-GCC to masz taki folder:

    \WinAVR-20080610\avr\include\avr


    zajrzyj tam sobie, masz tam definicje wszystkiego czego chcesz i do każdego procka w tym twojego




    poza tym ten twój kod ładnie się kompiluje i bez żadnych ostrzeżeń jeśli zrobisz tak:

    #include <avr\io.h> 
    #include <util\delay.h> 
    //#include <avr\signal.h> 
    #include <avr\interrupt.h> 


    zauważ że druga linijka jest zmieniona w stosunku do tego co ty zrobiłeś

    a trzecia linijka jest wywalona, i wszystko pięknie się teraz pięknie kompiluje (już bez żadnych warningów) i może nawet i by ruszyło u ciebie wtedy jeśli tak zrobisz ;)
  • #19 6174347
    boohoo
    Poziom 12  
    Cytat:
    gdyby tak poczytac dokumentacje
    Hm... Nie do końca tak to wygląda ze mną. Naprawdę staram się zaznajamiać z tematem, ale jak wspomniałem, stawiam pierwsze kroki w elektronice, uC w szczególności, czasem po prostu nie wiem gdzie czego szukać...

    Dobra, do rzeczy: PROBLEM ROZWIĄZANY! :)
    Spenetrowałem plik nagłówkowy iotn2313.h, podany przez mirekk36 i co się okazało?
    /* Interrupt vectors: */
    
    #define SIG_INT0          _VECTOR(1)  /* External Interrupt Request 0 */
    #define SIG_INT1          _VECTOR(2)  /* External Interrupt Request 1 */

    Po zmianie SIG_INTERRUPT0 na SIG_INT0, analogicznie dla drugiego przerwania, ku mej uciesze układ działa :P

    Dzięki wszystkim za pomoc, na przyszłość bardziej dokładnie postaram się wgryzać w dokumentacje :)
  • #20 6174502
    dawid512
    Poziom 32  
    Oznacza to również że posiadasz niezbyt aktualną wersje winavr bo w noej wersji dla tego wektora są aż 3 definicje.
  • #21 6174691
    janbernat
    Poziom 38  
    To oznacza że nie czytałeś też co podał ci Freddie Chopin
  • #22 6174847
    boohoo
    Poziom 12  
    -> dawid512 Rzeczywiście, mam wersję 20050214
    -> janbernat Mógłbyś jaśnie panie wyjaśnić, co masz na myśli? Czego wg Ciebie nie czytałem, bo nie umiem pojąć? Albo jestem ślepy, albo wartość Twojego postu jest zerowa!
  • #23 6175249
    Freddie Chopin
    Specjalista - Mikrokontrolery
    boohoo napisał:
    -> dawid512 Rzeczywiście, mam wersję 20050214

    OMG... 21 postow i ty dopiero teraz podajesz taka kluczowa informacje... to forum jest straszne...

    o czym my w ogole rozmawiamy, skoro ty masz wersje kompilatora sprzed CZTERECH LAT?

    4\/3!!
  • #24 6176030
    boohoo
    Poziom 12  
    Cóż... Być może Ty byłeś tak zdolny i w ciągu 2 tygodni od chwili, gdy po raz pierwszy ujrzałeś uC, wiedziałeś już wszystko, jednak ja o sobie tego nie mogę powiedzieć. Parokrotnie napisałem, że jestem początkującym. Ludzie, trochę wyrozumiałości... Nie wiedziałem, że mogą istnieć tego typu różnice między wersjami kompilatora.

    Zamykam temat, bo problem został rozwiązany, a nie chcę by temat został zaśmiecany lamentami nad moim karygodnym brakiem wiedzy...

    Dzięki wszystkim za zainteresowanie tematem,
    Pozdrawiam!
REKLAMA