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

Przyciski - wykonywanie czynności do określonego momentu

Nowinil 22 Gru 2011 10:44 1703 12
REKLAMA
  • #1 10290892
    Nowinil
    Poziom 9  
    Chciałbym wykonać funkcje do obsługi przetwornika A/C która po wciśnięciu przycisku wykonuje pomiary do czas aż nie wciśnęto innego przycisku. Poniżej zamieszczam kod który nie realizuje moich założeń. W poniższym kodzie nie wpisałem realizacji przetwarzania A/C zastąpiłem to migającą diodą. Wykorzystałem do tego funkcję do-while. Proszę o jakieś sugestie i podpowiedzi.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 10291890
    arnoldziq
    VIP Zasłużony dla elektroda
    Proszę podać o jaki procesor/mikro-kontroler chodzi.
  • #3 10294326
    Nowinil
    Poziom 9  
    Jest to Atmega32
    Przyciski po wciśnięciu wchodzą do pętli ale nie realizują pomiaru do określonego czasu. Funkcja wykonuje się tylko raz, także obsługa przycików jest ok tylko nie ma tego warunku do określonego momentu i przechodzenia na inne przyciski czyli inne kanały pomiarowe w moim przypadku. Liczę na waszą pomoc bo jest m to bardzo przydatne.
    Troszkę zawile opisałem moje założenie dlatego praktycznie go opiszę:
    1)wciskamy switch przyłączony do portu PA0 - wykonuje się pomiar napięcia
    2)pomiar cały czas się wykonuje dane zostają przetworzone i wyświetlone na LCD
    3)naciskam kolejny przyciski z 3 pozostałych dostępnych i w taki sam sposób dokonuje się pomiar.
    4)wszystkie te czynności wykonywane są na czterech przyciskach.
  • REKLAMA
  • #4 10294597
    tmf
    VIP Zasłużony dla elektroda
    Powinieneś rozdzielić sprawdzanie przycisków od wykonywanej czynności. Najlepiej sprawdzanie przycisków wrzucić w jakieś przerwanie (chociażby portu) i przy okazji zrealizować debouncing. Po sprawdzeniu ustawiasz odpowiednio flagę - każdy przycisk ma swój nr. Dzięki temu dopóki nie naciśniesz kolejnego przycisku flaga będzie miała wartość odpowiadającą poprzednio naciśniętemu przyciskowi. W programie głównym sprawdzasz flagę i w zależności od jej stanu wywołujesz odpowiedni efekt.
  • #5 10294729
    Nowinil
    Poziom 9  
    To co napisałeś wydaje mi się dość skomplikowane, pomógłbyś mi to zrealizować.
    Moje przerwania wyglądają tak
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    O debouncing'u znalazłem taki link https://www.elektroda.pl/rtvforum/topic1416904.html#6963559
    Nie wiem w jaki sposób to wszystko powiązać, mogę prosić o jakieś praktyczne podpowiedzi??
  • REKLAMA
  • #6 10294752
    kriss68
    Poziom 20  
    Wywal ! z while ( ! (PINC &
    0x01 )) ; czyli ma być while (PINC &
    0x01 ); oczywiście w każdym while to zmieniasz.
  • #7 10294763
    tmf
    VIP Zasłużony dla elektroda
    W książce do której jest link w mojej stopce są darmowe przykłądy do ściągnięcia. Masz tam m.in. implementację takiego sprawdzania przycisków.
    Ale ok, można to zrobić też na timerze. Więc po kolei - zainicjowałeś timer, teraz w procedurze obsługi jego przerwania sprawdzasz stan przycisków. Dzięki temu ich stan będzie okresowo sprawdzany. Potrzebujesz zmienną globalną, którą będziesz modyfikował w tej procedurze, a która będzie odzwierciedlać ostatnio naciśnięty przycisk.
    W programie głównym sprawdzasz po prostu jej stan. Dojdź do tego momentu, potem pomyślimy co dalej.
  • REKLAMA
  • #8 10294775
    Nowinil
    Poziom 9  
    Bez negacji nie zadziała przycisk bo musi być warunek - "jeśli bit nr. 0 rejestru PINC ma wartość "0""
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #9 10294796
    kriss68
    Poziom 20  
    Sprawdź a zobaczysz, że działa bo pętla while działa póki jej warunek jest różny od 0 a przyciski zawierają Ci do masy nie? Z wykrzyknikiem pętla będzie działać póki jest wciśnięty przycisk a bez póki jest puszczony.
  • #10 10294869
    Nowinil
    Poziom 9  
    Dzięki "kriss68" za trafną podpowiedź.

    Edytowałem posta, działa poprawnie z dwoma przyciskami. Błędnie mam ustawione przerwania i to chyba "miesza".


    "tmf" co do przerwania/timera którego kod wcześniej umieściłem to chyba źle obliczyłem. Znalazłem kalkulator na necie AvrCalc do obliczania OCR1A ale coś zrypałem. Mam zewnętrzny kwarc 16. I chciałbym aby przerwanie wykonywało się co 1s. Pomożecie mi zweryfikować moje dane. Chciałbym jeszcze wypróbować alternatywny sposób i nauczyć się obsługi przerwań/timerów.
  • #11 10294937
    kriss68
    Poziom 20  
    Prosta logika || sprawi, że trzeba oba przyciski wcisnąć a && sprawi, że trzeba będzie wcisnąć jeden z nich. Co do timera to timer1 w zwykłym trybie działania liczy od 0 do 65535 więc częstotliwość z jaką będzie się przepełniał to F_CPU/(prescaler*65536). Jak chcesz dokładniejszą częstotliwość to poczytaj o trybie CTC który zmniejsza liczbę do ktorej liczy timer. Wtedy częstotliwość to F_CPU/(prescaler*(OCR1A+1)).
  • #12 10296325
    Nowinil
    Poziom 9  
    Z preskalerem 64 ustawiłem wartość na OCR1A =249.
    Mam pytanie odnośnie eliminacji drgań styków. Pod spodem zamieszczam funkcję którą wykorzystałem ale nie przyniosła oczekiwanych rezultatów, ponieważ muszę długo przytrzymać przycisk aby naciśnięcie spowodowało wejście do funkcji.
    Przeczytałem, że można zrobić to za pomocą timerów ale nie wiem w jaki sposób u mnie to zrealizować.

    Ten sposób nie przyniósł oczekiwanych rezultatów:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Poniższy kod znalazłem na forum ale nie mogę dostosować do swojego programu.

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

    Możecie podpowiedzieć co znajduje się w tej funkcji: !RawKeyPressed() i w jaki sposób zmodyfikować pierwszą funkcję aby zaczęła poprawnie funkcjonować.
  • #13 10296597
    kriss68
    Poziom 20  
    Najprostsza wersja bez przerwań:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
REKLAMA