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.

Obsługa przycisków (przerwania i inne sposoby) w C/C++ Attiny2313

Kargul1000 18 Kwi 2014 20:42 1935 17
  • #1 18 Kwi 2014 20:42
    Kargul1000
    Poziom 8  

    Witajcie drodzy forumowicze. Buduję lampkę RGB na Attiny2313 i oto kod który już napisałem:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    I jak widać chciałem przyciskiem bistabilnym zmieniać poszczególne efekty zmiany kolorów, zmiany prędkości zmiany kolorów za pomocą funkcji switch...case...

    Ale to mi nie działa i chciałem do tego celu użyć przerwań o których wiem że istnieją ale nigdzie nie znalazłem prostego przykładu (C/C++) który by pokazywał jak jednym przyciskiem sprawić aby dioda się zapaliła potem klikając drugi raz dioda zaczęła mrugać itp itd.

    Prosiłbym o pomoc. z Góry dziękuję.

    0 17
  • #2 18 Kwi 2014 21:52
    McMonster
    Poziom 32  

    Switch to nie pętla, wykona się raz, zawsze na początku "licz" będzie równe 0 i utknie w nieskończonej pętli while.

    Zapewne przy kompilacji miałeś też wiele warningów na użycie delay, które zignorowałeś.

    0
  • #4 19 Kwi 2014 16:24
    Kargul1000
    Poziom 8  

    Dziękuję za szybką odpowiedź. Właśnie podczas kompilacji żadnych błędów na temat delay. Tak oczywiście wiem jak działa switch. Założenie jest takie żeby żeby przechwycić wciśnięcie przycisku bistabilnego i licz++; if(licz == 4){licz=0;} i właśnie zatrzymałem się na metodzie przechwycenia tego przycisku żeby w każdej chwili działania programu dało się go przycisnąć aby zwiększyć zmienną licz.

    Ale moje rozwiązanie nie działa tak jak bym tego chciał przydały by się przerwania:)
    Jesli licz ==0 to wykonuje się default
    licz == 1 to case 1: itp itd.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    A oto wynik działania kompilacji:

    >> ./kompilacja.sh
    In file included from program.c:14:0:
    /usr/lib/gcc/avr/4.7.2/../../../avr/include/util/delay.h:95:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed" [-Wcpp]
    /usr/lib/gcc/avr/4.7.2/../../../avr/bin/ld: program.o section `.text' will not fit in region `text'
    /usr/lib/gcc/avr/4.7.2/../../../avr/bin/ld: region `text' overflowed by 15762 bytes
    collect2: error: ld returned 1 exit status
    avr-objcopy: 'program.o': No such file
    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x1e910a
    avrdude: erasing chip
    avrdude: safemode: Fuses OK
    avrdude done. Thank you.
    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x1e910a
    avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
    To disable this feature, specify the -D option.
    avrdude: erasing chip
    avrdude: reading input file "program.hex"
    avrdude: input file program.hex auto detected as Intel Hex
    avrdude: writing flash (1328 bytes):

    Writing | ################################################## | 100% 6.76s

    avrdude: 1328 bytes of flash written
    avrdude: verifying flash memory against program.hex:
    avrdude: load data flash data from input file program.hex:
    avrdude: input file program.hex auto detected as Intel Hex
    avrdude: input file program.hex contains 1328 bytes
    avrdude: reading on-chip flash data:

    Reading | ################################################## | 100% 5.74s

    avrdude: verifying ...
    avrdude: 1328 bytes of flash verified
    avrdude: safemode: Fuses OK
    avrdude done. Thank you.

    0
  • #5 19 Kwi 2014 16:43
    mi14chal
    Poziom 28  

    Przeczytaj to:

    Cytat:
    /usr/lib/gcc/avr/4.7.2/../../../avr/include/util/delay.h:95:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed" [-Wcpp]
    /usr/lib/gcc/avr/4.7.2/../../../avr/bin/ld: program.o section `.text' will not fit in region `text'
    /usr/lib/gcc/avr/4.7.2/../../../avr/bin/ld: region `text' overflowed by 15762 bytes
    collect2: error: ld returned 1 exit status


    Masz napisane że trzeba włączyć optymalizacje i że program jest za duży na ten uC.

    0
  • #6 19 Kwi 2014 16:53
    Kargul1000
    Poziom 8  

    Ouuu :D faktycznie, ale program działa załadowało do attiny2313 i lampka zmienia kolory :)

    0
  • #7 19 Kwi 2014 17:14
    mi14chal
    Poziom 28  

    Na pewno nie ten, którego kompilacja się nie powiodła.

    0
  • #8 19 Kwi 2014 17:41
    Kargul1000
    Poziom 8  

    No ale serio działa ten ponieważ jak coś zmienię w efekcie zmiany koloru to widzę różnicę w działaniu lampki :)

    Dodano po 13 [minuty]:

    Prosiłbym o prosty przykład implementacji wykorzystania przerwania w języku C na attiny2313. Jedna dioda jeden przycisk bistabilny po naciśnięciu raz dioda się zapala po nacisnieciu kolejny dioda miga i kolejny dioda powoli wygasa.

    0
  • #10 19 Kwi 2014 19:27
    Kargul1000
    Poziom 8  

    No tak zauważyłem wgrywa sie tylko 1368 bytes z 17518 bytes

    0
  • #11 20 Kwi 2014 12:12
    Kargul1000
    Poziom 8  

    Ok zrobiłem

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Działa tak jak planowałem :) teraz przydałyby się przerwania bo nie wiem jak wyjść z rand(); w case 5: :)

    0
  • #12 20 Kwi 2014 14:36
    McMonster
    Poziom 32  

    Co masz na myśli przez "wyjść z rand()"? Chyba nie bardzo rozumiesz sens przerwań.

    0
  • #13 20 Kwi 2014 14:53
    Kargul1000
    Poziom 8  

    No wiem jak działa przerwanie i właśnie chodzi mi o to aby w każdym momencie gdy zostanie wciśnięty przycisk następowała jakaś akcja, w moim przypadku zmiana efektu. Teraz też w sumie działa, ale gdy w ostatnim case zacznie być generowana liczba pseudo losowa przyciśnięcie klawisza, nawet jego przytrzymywanie nic nie powoduje :) Dlatego prosi się aż o zastosowanie przerwania i wywołać inną akcję.

    Mile widziany by był jakiś prosty przykład wykorzystania przycisku bistabilnego i IRQ. Implementacja w języku C/C++ oczywiście.

    0
  • #14 20 Kwi 2014 15:01
    mi14chal
    Poziom 28  

    Po pierwsze przycisk powinno się odczytywać w przerwaniu, żeby wyeliminować drgania styków. Po drugie program tak piszesz, że nie da się go czytać. Po trzecie widzisz w ogóle różnicę pomiędzy C a C++? Bo to co pokazujesz jest tylko w C.

    0
  • #15 20 Kwi 2014 15:26
    Kargul1000
    Poziom 8  

    Oczywiście to co pokazuję jest w C ale jestem otwarty na pomoc i propozycję rozwiązań mojego problemu z tego względu jest napisane powyżej, w moim poprzednim poście "...C/C++...". C czy C++ nie jest mi straszne i tym bardziej obce.

    Drgania wyeliminowałem jak na razie sprzętowo i tak zgodzę się odczyt odczyt przycisku w przerwaniu. Podpowiedzcie mi to czego nie wiem bo jak na razie liczba zbędnych postów w moim temacie jest większa od tych pomocnych.

    Nie da się kodu czytać śmieszne... Znasz C umiesz przeczytać każdy kod, bez przesady! Po co jest to forum ? Dla cwaniaczków którym nie podobają się wcięcia w kodzie ? Czy między innymi dla kulturalnych ludzi którzy chcą rozszerzyć swoją wiedzę o Avr-y i nie tylko?

    0
  • #16 21 Kwi 2014 20:15
    pawel_konin
    Poziom 20  

    Kargul1000 napisał:
    Oczywiście to co pokazuję jest w C ale jestem otwarty na pomoc i propozycję rozwiązań mojego problemu z tego względu jest napisane powyżej, w moim poprzednim poście "...C/C++...". C czy C++ nie jest mi straszne i tym bardziej obce.

    Drgania wyeliminowałem jak na razie sprzętowo i tak zgodzę się odczyt odczyt przycisku w przerwaniu. Podpowiedzcie mi to czego nie wiem bo jak na razie liczba zbędnych postów w moim temacie jest większa od tych pomocnych.

    Nie da się kodu czytać śmieszne... Znasz C umiesz przeczytać każdy kod, bez przesady! Po co jest to forum ? Dla cwaniaczków którym nie podobają się wcięcia w kodzie ? Czy między innymi dla kulturalnych ludzi którzy chcą rozszerzyć swoją wiedzę o Avr-y i nie tylko?


    Witam
    Jak chcesz używać przerwań to musisz w zasadzie pół programu zmienić gdyż:

    -Programowo nie eliminujesz drgań styków pisanie robię to sprzętowo nie jest eleganckie i w 100% pewne.
    -Masz masę delay`y co słusznie ci wytknięto które nie mają prawa znaleźć się przerwaniu.
    -Jak widać masz pętle for które kłóci się z przerwaniem(przerwanie to defakto tak cykliczna "pętla" więc wyszło by ci pętla w "pętli=program w malinach".
    -Obciążasz takim kodem maksymalnie CPU( co chwile czekasz po 0.5s albo Bóg wie ile) a lepiej żeby procesor oddychnął.

    Więc zrób tak:

    Zdefiniuj jakiś timer nawet sprzętowy na jakąś sensowną dokładność (prescaler i wartość początkowa timera). Następnie sprawdź czy wcisnąłeś przycisk zapisz do zmiennej nawet globalnej odlicz jakiś czas i po tym czasie sprawdź czy stany są sobie równe to przed i po (najlepiej wszystko w przerwaniu). Wtedy wstaw sobie tego switcha w przerwaniu i casy jakie sobie tam wymyśliłeś. Wtedy uzależniasz np flagą po eliminacji drgań styków zmianę jakiś wartości, czy też uruchamiasz jakąś inna szybkość zmian itp. Taki algorytm stosujesz dla każdego przycisku nie przyglądałem się głęboko w twój kod gdyż to tasiemiec kiepsko czytelny. Z tego co udało mi się rozszyfrować potrzeba ci 1 przyciski "opcja do przełączania casów" i zdefiniowane czasy oczywiście odliczone w tym timerze na przerwaniach. I Parę zmiennych globalnych, nie zapomnij o volatile. Po prostu kombinuj bo nikt nie odrobi za ciebie zadania. Spróbuj uruchomić timer przerwania i eliminacje drgań styków i żeby od tego przycisku zmieniały się te opcje które masz zdefiniowane a wtedy uzyskasz jakąś pomoc ale musisz się wykazać że coś zrobiłeś sam. To co masz zrobione to jest prosty sposób jak wykorzystać procesor tylko do migania diodą nic więcej na tym procesorze nie zrobisz gdyż jak mówiłem cały czas gdzieś czekasz Bóg wie za czym.

    Pozdrawiam
    Paweł

    0
  • #17 21 Kwi 2014 21:01
    Tomq
    Poziom 38  

    Co do eliminacji drgań.
    Można też tak: wciśnięto klawisz, wykonujesz akcje z nim związaną i kasujesz jakiś licznik i teraz choćby program odczytał kolejne wciśnięcie klawisza (drgania) to ignorujesz to przez czas drgań styków. Brzmi zawile, ale jest banalne:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    O samych timerach i przerwaniach z nimi związanymi:
    http://diycenter.acid19.linuxpl.com/readarticle.php?article_id=3
    http://maxembedded.com/2011/07/14/avr-timers-ctc-mode/

    0
  • #18 21 Kwi 2014 21:24
    Kargul1000
    Poziom 8  

    Dzięki za rozjaśnienie :) i takich podpowiedzi więcej :) Dopiero się uczę programowania Avr-ów przyda się do Systemów wbudowanych.

    0