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.

[Rozwiązano] Klikanie klawiszami - Dlaczego nie działa

5657jz 27 Wrz 2018 11:59 684 22
  • Poziom 14  
    Głupi to temat, ale nie nie rozumiem działania uC.

    O co chodzi.
    Przyciskając klawisz, wybieram z menu obsługę (prog. do wykonania) znajdujący sie
    pod w/w.

    W pętli głównej znajduje sie:
    Code:
    [syntax=c]
    

    void spr_SW(void)
    {
          if(!(KLIK_MENU))  // tu losowo nie sprawdza klawisza
          {
             _delay_ms(WAIT);
             menu();            // // tu losowo nie sprawdza klawisza.  Jak wejdzie do menu(), klawisze działaja poprawnie
             _delay_ms(50);
          }
          
           if(!(KLIK_ENTER)) // tu losowo nie sprawdza klawisza
          {
             _delay_ms(WAIT);
             lcd_clrscr();
             _delay_ms(18);
             lcd_puts("PROG.START");
             _delay_ms(500);
          }
          
           if((!(KLIK_PLUS)) || (!(KLIK_MINUS)) ) // tu losowo nie sprawdza klawisza
          {
             _delay_ms(WAIT);
             przesun();
             _delay_ms(50);
          }  //przesuń karetkę
          
           if(!(KLIK_PAUSE))   // tu losowo nie sprawdza klawisza
          {
             _delay_ms(WAIT);
             pause();
             _delay_ms(50);
          }
          [/syntax]


    Po uruchomieniu, uC samoczynnie- losowo uruchamia podprogramy znajdujące sie pod klawiszami.
    Jedynie, jeśli wejdzie do menu(). uC uspokaja się i klawisze czekają na naciśnięcie.

    Co może być przyczyną takiego zachowania uC w pętli głównej.
    Za wskazówkę serdeczne dzięki.
  • Poziom 23  
    Zakładam, że przyciski są podłączone do pinów i zdefiniowane jako KLIK_MENU itd. Nie sprawdzaj w pętli głównej stanu przycisków tylko wrzuć sprawdzanie do przerwania od któregoś timera z ustawianiem wartości jakiejś flagi a w pętli głównej wykorzystaj funkcję switch - case.
    Poza tym nie widzę inicjacji portów.
  • Poziom 14  
    1. Niestety timery będą mi potrzebne do innych celów.
    2. Boję się pomyśleć, jak w pętli głównej wstawię if() do innych celów.
    -chyba nie tędy droga ?
    Ponawiam pytanie -czemu tak się może zachowywać
  • Poziom 34  
    Do obsługi klawiszy służą przerwania zewnętrzne intX oraz pcint ,tam masz możliwość konfiguracji pinów ,które wywołują przerwanie. Ewentualnie musisz napisać programową pętlę która będzie sprawdzała stan wejść pamiętając o drganiu styków i temu podobnych zjawiskach . Musisz też pamiętać że program musi bezustannie sprawdzać stan wyprowadzeń żeby reagował na zmiany więc moim zdaniem odpytywanie o stan wyprowadzeń ma sens tam gdzie wszystkie reakcje są wywołane działaniem klawiatury np. zamek szyfrowy . W innych przypadkach lepszym rozwiązaniem jest "przerwaniowa" obsługa klawiatury i klawiszy.
  • Poziom 32  
    Pewnie procesor nawet nie wchodzi do przedstawionej funkcji - problem jest gdzieś indziej. Może jest zajęty przerwaniem? Domyślam się, że podciąganie jest włączone.
  • Poziom 14  
    Ku wyjasnieniu.

    Program dopiero ma się rozwijać.
    Puki co, funkcje wykonywane pod klawiszami - to tylko informacyjnie , aby wiedzieć gdzie aktualnie się znajduje (debugowanie).
    Układ wykonany na "pajaku" + płytka ewaluacyjna.
    Płytka dobra. Kontakt przewodów również.

    Generalnie chodzi oto że : wchodząc do spr_SW(), if()-y nie działają poprawnie tz losowo przyjmują wartość 1.
    jeśli losowo if(!(KLIK_MENU)) przyjmie wartość 1.
    Wykonuje się menu();
    Ta funkcja (menu()) , zbudowana identycznie jak spr_SW() - działa prawidłowo
    Każdy klawisz jest poprawnie odczytywany. ( Pomimo jak można zarzucić że, coś nie łączy, coś jest zepsute, coś jest zwarte.)
    Nie pchnę swojego projektu dalej, puki mi nie będzie to, o czym wyżej.

    Niestety, nie wiem gdzie szukać błędu.
  • Poziom 36  
    Wydaje się, że powinieneś w pierwszej kolejności prawidłowo zrealizować maskowanie drgań przycisków, czyli za pomocą timera.
    5657jz napisał:
    Niestety timery będą mi potrzebne do innych celów

    Timery dość spokojnie mogą realizować kilka różnych funkcji.
  • Specjalista - Mikrokontrolery
    Brak schematu (inicjowanie portów), brak kodu, brak wróżki na forum.
    Za to jest Kamyczek, co chce przyciski w przerwaniu portu obsługiwać... Kamyczku, sto razy pisaliśmy, że tego NIE należy robić.
  • Poziom 14  
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Poziom 34  
    BlueDraco napisał:
    Brak schematu (inicjowanie portów), brak kodu, brak wróżki na forum.
    Za to jest Kamyczek, co chce przyciski w przerwaniu portu obsługiwać... Kamyczku, sto razy pisaliśmy, że tego NIE należy robić.


    Wszystko kolego zależy od aplikacji i tego co jest ważniejsze . Twoim zdaniem lepiej skanować porty i zajmować czas mikrokontrolera na bezsensowne sprawdzanie czy się ktoś skusił i przycisnął przycisk niż wykonywanie innych i ważniejszych rzeczy . Obsługując przyciski w przerwaniu wykonujesz skok do przerwania na kilka cykli gdy to nastąpi naciśnięcie zajmuje to naście cykli a przez resztę czasu mikrokontroler robi inne rzeczy lub nie robi nić. Może więc kolego zdemontujesz sobie dzwonek przy drzwiach i będziesz tam biegał co minutę sprawdzić czy ktoś pod nimi stoi .. Bo tak wygląda aktualnie twoja teoria ...
  • Poziom 36  
    kamyczek napisał:
    BlueDraco napisał:
    Brak schematu (inicjowanie portów), brak kodu, brak wróżki na forum.
    Za to jest Kamyczek, co chce przyciski w przerwaniu portu obsługiwać... Kamyczku, sto razy pisaliśmy, że tego NIE należy robić.


    Wszystko kolego zależy od aplikacji i tego co jest ważniejsze . Twoim zdaniem lepiej skanować porty i zajmować czas mikrokontrolera na bezsensowne sprawdzanie czy się ktoś skusił i przycisnął przycisk niż wykonywanie innych i ważniejszych rzeczy . Obsługując przyciski w przerwaniu wykonujesz skok do przerwania na kilka cykli gdy to nastąpi naciśnięcie zajmuje to naście cykli a przez resztę czasu mikrokontroler robi inne rzeczy lub nie robi nić. Może więc kolego zdemontujesz sobie dzwonek przy drzwiach i będziesz tam biegał co minutę sprawdzić czy ktoś pod nimi stoi .. Bo tak wygląda aktualnie twoja teoria ...

    Teoretycznie można zrobić tak jak piszesz bo teoretycznie można zrobić niemal wszystko ale ...
    Po pierwsze, ze względu na drgania styków, zrobienie tego nie jest aż tak trywialne jak wynikałoby z Twojego ogólnikowego i lakonicznego opisu, jakoś trzeba maskować te drgania, zapewne blokując przerwania jakimś timerem, jak się flagi przerwań, timerów i czego tam jeszcze zaczną ganiać po programie, to może on zacząć działać zgoła inaczej niż według intencji programisty, szczególnie jeżeli programista jest niezbyt doświadczony.
    Po drugie, mówiąc uczciwie, nie słyszałem o systemie, który by miał tak napięty "budżet cykli maszynowych" żeby w przerwaniu zegarowym nie dało się wcisnąć raptem kilku instrukcji do obsługi klawikordu, szczególnie że w Twoim rozwiązaniu, po wciśnięciu guzika, jakieś ekstra instrukcje też muszą się wykonać. Większość kolegów, którzy się tu wypowiadają, opisałaby taki system jako po prostu źle zaprojektowany.
    Przykład z dzwonkiem jest o tyle bez sensu, że gdybym naprawdę nie miał nic do roboty i nudził się jak mops, chętnie bym pobiegał do drzwi - ot tak, dla zdrowotności.
  • Poziom 14  
    Panowie.
    Klikanie klawiszami i zapalanie diod, to coś co polecają w przedszkolu.
    A tu. temat tak się rozwija ....

    Mój uC. praktycznie nic nie będzie robił.
    Kilka funkcji wywoływanych klawiszami, to tylko wpisanie parametrów. Które z kolei
    zostaną przeliczone . Następnie uruchomiona zostanie maszyna-to będzie właściwy program z przerwaniami od timerów i czujników.

    Nie rozumiem dlaczego spr_SW() nie działa prawidłowo. A menu() jest OK.
    Kompilator nie zgłasza żadnych błędów.
    Może pętla główna powinna być bardziej rozbudowana ? Teraz zawiera tylko:{spr_SW(); asm ("NOP"); asm ("NOP");}


    Ps. Dzwonka nie będę demontował. Założę elektro-zamek i otworze go "kliknięciem"
    albo przejdę się pieszo i otworzę furtkę z klucza - tak dla zdrowotności.
  • Specjalista - Mikrokontrolery
    Schematu nadal nie mamy, wewnętrzne podciągnięcia nie włączone. Zgaduję, że wewnętrznych brak i stąd duchy.

    Kamyczku - lepiej już zamilknij, bo pogrążasz się każdym zdaniem.

    Tak z praktyki - w każdym projekcie jest potrzebne przerwanie timera. W tym przerwaniu np. 50 razy na sekundę trzeba sprawdzić przycisk. Zajmuje to 2 linijki kodu.
  • Poziom 34  
    BlueDraco napisał:
    Kamyczku - lepiej już zamilknij, bo pogrążasz się każdym zdaniem

    Nie życzę sobie takich zwrotów....

    W ciągu sekundy jak się postarasz naciśniesz przycisk 4 razy więc 46 razy wykonasz to sprawdzenie bezsensownie . W pcint przerwanie wykona się 4 razy i wykona to te same dwa cykle . Plus cykle które wykonuje mikrokontroler przy skoku i powrocie z przerwania czyli kolejne 4 cykle tym sposobem Kolega robi 50*6 czyli 300 a przy pcint będzie to 4*6 cykli czyli 24 . Jest to jednoznaczne z 12 krotnie większym obciążaniem mikrokontrolera A czy to jest dobre rozwiązanie niech sobie każdy osądzi sam . Są przecież specjaliści którzy wszystko wiedzą najlepiej a innym każą się zamknąć ...
  • Poziom 18  
    kamyczek napisał:
    W pcint przerwanie wykona się 4 razy i wykona to te same dwa cykle

    Każde wduszenie przycisku wygeneruje kilka/naście/dziesiąt odbić i tyle samo wywołań procedury obsługi przerwania. Warto by je doliczyć do rachunku.
    Ale nawet bez ich uwględnienia:
    kamyczek napisał:
    tym sposobem Kolega robi 50*6 czyli 300 a przy pcint będzie to 4*6 cykli czyli 24 . Jest to jednoznaczne z 12 krotnie większym obciążaniem mikrokontrolera

    300-24 = 276. Dla procka napędzanego, nie tak specjalnie szybkim, rezonatorem 8MHz jest to oszczędność 276/8000000=0,00345% cykli pracy procesora, czyli praktycznie 0.

    Dla przerwania od klawisza widzę zastosowanie przy wybudzaniu procka z uśpienia, ale z założeniem, że w procedurze obsługi przerwanie jest dezaktywowane i obsługa klawisza dalej odbywa się koszernie, testowaniem w przerwaniu timera.
  • Poziom 34  
    ex-or napisał:
    Każde wduszenie przycisku wygeneruje kilka/naście/dziesiąt odbić i tyle samo wywołań procedury obsługi przerwania. Warto by je doliczyć do rachunku.
    Ale nawet bez ich uwględnienia:

    Owszem ale tylko w przypadku ,kiedy nie zablokujesz przerwania pcint na czas drgania styków . Tak samo stanie się w przypadku odpytywania też musisz wykonać procedurę związaną z drganiem styków więc w czym widzisz problem ? W tym że po wejściu w przerwanie blokujesz kolejne i ustawiasz wskaźnik żeby odczekać określony czas i włączyć ponownie przerwania po jego upłynięciu ? Procedura drgania styków dotyczy każdego sposobu realizacji zagadnienia przycisku obsługiwanego w przerwaniu jak i programowo .
  • Poziom 14  
    Pany. Pomożecie coś. Czy tak Będziecie się spierać ile drgań nastąpi .....

    Piny podciągnięte są zewnętrznymi rezystorami (PINx=1).
    O drganiach styku, nie rozmawiajmy. Bo jak styk przycisku jest rozwarty -to nie drży.
    Natomiast odpytanie "czy styk jest zwarty do masy" (!(KLIK_MENU)) ==1, pomimo PINx znajduje się w stanie wysokim.
    I to cały problem z pytaniem - DLACZEGO tak się dzieje.

    A przyłączając się do dyskusji: Sprawdzanie kliknięcia przycisku timerami, przerwaniami to przerost formy nad treścią. ( chyba że, to awaryjny wyłącznik).


    Drgania styków, załatwia "_delay_ms(WAIT);" gdzie WAIT może trwać 20ms, jak mało to 120ms. A sama reakcja na zmianę stanu PINu to 1,5 cyklu zegara.
    Tak więc, klikniecie niech trwa 5ms i drga ,i tak zostanie sprawdzone tylko jeden raz.
    Zgodzę się ze sprawdzeniem pinów w przerwaniach, ale jak pętla główna ma z dużo roboty a zegar 1MHz.

    Pomóżcie. albo zamknę ten temat.
  • Poziom 34  
    Zrób sprawdzenie dwuetapowo sprawdź stan jak jest 0 to poczekaj aż wróci ponownie do stanu 1 . Dla mnie to dziwne że tak działa . Jakiego używasz mikrokontrolera , jakie wartości rezystorów podciągających zastosowałeś . Może w układzie powstają jakieś zakłócenia ,które przekłamują stan . Do przycisków zazwyczaj wystarczają rezystory wewnętrzne służące do podciągania i nie ma potrzeby stosowania zewnętrznych powieś kawałek schematu to zobaczymy co w trawie piszczy
  • Poziom 18  
    No więc z tego co widać:
    Inicjację portów masz źle, co prawda chyba osiągnąłeś to co chciałeś ale tylko przypadkiem. Rozumiem, że zamierzałeś wyzerować rejsestry DDR i PORT na pinach przycisków. Powinieneś zrobić tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    co jest równoważne
    Kod: c
    Zaloguj się, aby zobaczyć kod

    czyli
    Kod: c
    Zaloguj się, aby zobaczyć kod

    A zrobiłeś :
    Kod: c
    Zaloguj się, aby zobaczyć kod

    czyli
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Ratuje Cię fakt że wartość tych rejestrów po resecie i tak jest równa zero.

    Po drugie. "Debouncing" delayami jest nie do przyjęcia. Nie ma to tamto, że niby program prosty i powinno działać. Powinno albo i nie. Nie jesteś w stanie prawidłowo przeanalizować zachowania układu. Funkcja interpretująca batony MUSI otrzymać stan buttona już oczyszczony z drgań. Tak więc dyskusja o debouncingu nie jest tutaj offtopem a wręcz przeciwnie.

    No i po trzecie: Jak nie pokażesz całego całego kodu oraz, prawdopodobnie, schematu to tylko wróżka będzie w stanie odpowiedzieć ""czy styk jest zwarty do masy" (!(KLIK_MENU)) ==1, pomimo PINx znajduje się w stanie wysokim. "
  • Specjalista - Mikrokontrolery
    Zafiksowany Kamyczku. Wykrycie naciśnięcia przecisku w przerwaniu timera - to 2 linijki kodu w C, wykonywane 50 razy na sekundę. Ty proponujesz rozwiązanie wymagające przerwania od przycisku, w którym to przerwaniu należy zablokować to przerwanie, ustawić znacznik/timer programowy, a następnie w przerwaniu timera odblokować przerwanie przycisku. Mamy więc timery programowe oddzielne dla każdego przycisku, modyfikowane w przerwaniu timera, co zajmie trzy linijki kodu w przerwaniu timera na każdy przycisk. Czyli: obsługa przerwania timera po 3 linie kodu na przycisk plus obsługa przerwania przycisku - jakieś 3-4 linijki na przycisk.

    Temat wałkowany ze sto razy, a Ty wciąż się upierasz...
  • Poziom 14  
    do ex-or
    To wytłumacz mi to: Dlaczego po wejściu do funkcji menu(); wszystkie PINx
    odczytywane są prawidłowo i menu działa bezbłędnie. Przy tych samych ustawieniach
    portów tz. DDR=0 -> wejście PORT=0 -> wysoka impedancja
    Schemat ? Odsyłam do załącznika -tam schemat płytki ewaluacyjnej.EVBavr05..l.pdf Download (865.96 kB)
  • Poziom 18  
    Z dostępnych strzępków kodu i schematu nie można stwierdzić.
    W ramach debugowania w stylu hit&miss możesz przed wejściem do pętli głównej ustawić długi, np. 1s, delay żeby wyeliminować domniemane stany nieustalone. Które nie wiem skąd by się miały wziąć, ale co innego pozostaje w tym stanie świadomości?:lol:
  • Poziom 14  
    Po włączeniu Fuse_bitu CKOPT -wszystko działa poprawnie.
    Dlaczego? Nie bardzo rozumiem jaki ma wpływ.