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

[C][ATmega8]Zmiana sekwencji programu button switch

jakubajak19 17 Maj 2019 22:09 1356 26
  • #1 17966459
    jakubajak19
    Poziom 6  
    [/tex]Witam od niedawna uczę sie programować avr-y i natknąłem się na problem którego nie potrafię rozwiązać .
    Próbowałem stworzyć program który zmienia sekwencje świecenia diod LED po naciśnięciu Button switcha .
    Czy mógłby ktoś zerknąć na ten program i zaproponować jakieś zmiany ?? i wytłumaczyć przy okazji jak zliczać przerwania > Dziękuję z góry, poniżej to co udało mi się stworzyć.
    [C][ATmega8]Zmiana sekwencji programu button switch
    https://www.youtube.com/watch?v=tMmXIQfZqGg
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #2 17966541
    LChucki
    Poziom 31  
    Sformatuj kod i umieść w znacznikach syntax.
    Nie używa się delay w przerwaniu.
    LED bez rezystorów ograniczających prąd?

    jakubajak19 napisał:
    i wytłumaczyć przy okazji jak zliczać przerwania

    O co dokładnie chodzi?
    Zliczanie impulsów, np licznik częstotliwości?
    Na razie to uaktywniłeś INT0, zliczać możesz inkrementując zmienną w procedurze obsługi przerwania.


    Zamiast Mega8, użyj Megi88, która ma debuger.

    Dodano po 4 [minuty]:

    jakubajak19 napisał:
    Próbowałem stworzyć program który zmienia sekwencje świecenia diod LED po naciśnięciu Button switcha .

    I nie działa, nic dziwnego
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Debuger by pomógł ale możesz użyć symulatora, z tym, ze na początek wyłącz optymalizację.
  • #4 17966595
    Konto nie istnieje
    Poziom 1  
  • #5 17966891
    jakubajak19
    Poziom 6  
    LChucki napisał:
    Sformatuj kod i umieść w znacznikach syntax.
    Nie używa się delay w przerwaniu.
    LED bez rezystorów ograniczających prąd?
    dlatego bez rezystorów bo to układ do symulacji i w tym programie nie jest wymagane ograniczenie rezystorem w rzeczywistym układzie mam podłączone rezystory

    [

    Zamiast Mega8, użyj Megi88, która ma debuger.
    niestety w rzeczywistości posiadam Atmege8
    Dodano po 4 [minuty]:

    jakubajak19 napisał:
    Próbowałem stworzyć program który zmienia sekwencje świecenia diod LED po naciśnięciu Button switcha .

    I nie działa, nic dziwnego
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Debuger by pomógł ale możesz użyć symulatora, z tym, ze na początek wyłącz optymalizację.

    z tym sobie poradziłem ale nie przez symulator tylko przez zastosowanie volatile int.
    Program działa z tym że gdy w przerwaniu usuwam z poniższego fragmentu _delay_ms() to przestaje działać :
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Przy takim Kodzie jak zaktualizowałem w symulatorze działa , jeszcze nie wiem jak na rzeczywistym układzie .
    Czy ktoś mógłby mi wytłumaczyć co wstawić zamiast _delay_ms(50) żeby było poprawnie i żęby to działało ??
  • Pomocny post
    #6 17967032
    LChucki
    Poziom 31  
    Przerwanie od INT0 powinno aktywować przerwania od timera, które co 50ms będą zmieniać stan portu c:
    INT0:
    - blokuj przerwania INT0
    - licznik sekwencji na portc = 0
    - aktywuj przerwanie timera

    INT TIMERA:
    - switch (licznik sekwencji) .....
    w ostatnik case czy default:
    1) blokuj przerwania timera
    2) kasuj flagę INT0
    3) włącz przerwania int0
  • #7 17967574
    BlueDraco
    Specjalista - Mikrokontrolery
    Zupełnie zły pomysł. Przerwanie timera 50 Hz sprawdza stan przycisku. Przy wykryciu wciśnięcia przestawia zmienną określającą kierunek. Co któreś przerwanie na podstawie zmiennej kierunku zmieniamy sterowanie diod. Na oko max. 20 linii kodu w całym programie. - zainicjować port i timer - 4 line, test przycisku - 4 line., odliczanie i zmiana - pewnie tyleż.
  • #8 18046491
    jakubajak19
    Poziom 6  
    Jakiś fizyczny sposób załączenia przerwania timera przerwaniem od INT0 . Szukam i nie mogę znaleźć żadnych przykładów ani bardziej szczegółowego opisu jak to ugryźć , we wcześniejszych odpowiedziach nikt nie napisał dlaczego nie można używać delay w przerwaniu a w prostej wersji programu nie wpływało to na działanie. Teraz mam bardziej rozwinięta wersje i nie działa
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    [C][ATmega8]Zmiana sekwencji programu button switch
    dodaje schemat w rzeczywistym układzie mam rezystory ten układ działa w symulacji niestety w rzeczywistości nie działa poprawnie

    Dodano po 6 [minuty]:

    BlueDraco napisał:
    Zupełnie zły pomysł. Przerwanie timera 50 Hz sprawdza stan przycisku. Przy wykryciu wciśnięcia przestawia zmienną określającą kierunek. Co któreś przerwanie na podstawie zmiennej kierunku zmieniamy sterowanie diod. Na oko max. 20 linii kodu w całym programie. - zainicjować port i timer - 4 line, test przycisku - 4 line., odliczanie i zmiana - pewnie tyleż.

    Zły pomysł przedstawiłem czy chodzi o pomysł LALECZKACZAKI ?? i jak to powinno wyglądać żeby było dobrze i działało ??
  • #9 18046578
    BlueDraco
    Specjalista - Mikrokontrolery
    Złym pomysłem jest użycie przerwania INT - potrzebny tylko przerwanie timera. W tekócie, który zacytowałeś, napisałem jak to powinno wyglądać. Po prostu tak zrób.
  • #10 18159369
    jakubajak19
    Poziom 6  
    Witam, zrobiłem tak jak napisano wyżej z tym przerwaniem od timera ,niestety dalej to nie działa jak chce przerobiłem trochę schemat zeby łatwiej sprawdzić co jest grane i dopisałem kilka linijek od siebie ;/ niestety działa to tak że program zmieni się gdy trzymam przycisk ale po puszczeniu go wyrzuca go do do opcji default... nie rozumiem do końca jak mam to zmienić żeby działało na zasadzie wybierania switchem podprogramu ... jakby ktoś mógł wytknąć błędy lub coś więcej podpowiedzieć jak to zrobić i dlaczego tak a nie inaczej

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

    https://filmy.elektroda.pl/22_1568029588.mp4
  • Pomocny post
    #11 18163956
    mpier
    Poziom 29  
    Witam, zastanów się co się dzieje w switch (OPCJA) dla PRZEL == 1. Jak będziesz wiedział jak działa switch...case, możesz wykorzystać go do migania diodami bez ciągłego delay między nimi i blokowania całego programu.
  • #12 18174522
    jakubajak19
    Poziom 6  
    mpier napisał:
    Witam, zastanów się co się dzieje w switch (OPCJA) dla PRZEL == 1. Jak będziesz wiedział jak działa switch...case, możesz wykorzystać go do migania diodami bez ciągłego delay między nimi i blokowania całego programu.


    PRZEL==1 jest chyba niepotrzebne bo z case... wychodzi po zakończeniu instrukcji tak ?? a w każdego case'a powinno wejść w zależności od tego ile razy został wciśnięty przycisk , niestety dzieje się tak że wchodzi w tą opcje do której jest powrót w default jak wpisze w default OPCJA=1 to program działa cały czas na case 2 jak jest tam wartość 2 to na case 3 itp w momencie gdy wcisnę przycisk i trzymam to przeskakuje do kolejnego case'a ale tylko wtedy gdy trzymam nie wiem czemu sie tak dzieje jeśli wiesz to prosze o wytłumaczenie

    Dodano po 1 [godziny] 34 [minuty]:


    Juz zadziałało tylko jeszcze jeden mały problem jest ... jeśli chodzi o zmianę sekwencji swiecenia to zacina się czasami przy zmianie lub przeskakuje jedną z sekwencji o co chodzi ktoś podpowie ??
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #13 18175020
    mpier
    Poziom 29  
    Jaka jest aktualna częstotliwość zegara? Jak często uruchamiane jest przerwanie? Ile trwa naciśnięcie przycisku? Musisz zmieniać opcje tylko kiedy przycisk został naciśnięty, nie przytrzymany. Dodaj do przerwania warunek sprawdzający poprzedni stan przycisku. Pomyśl nad wyeliminowaniem delay.
  • #14 18175544
    jakubajak19
    Poziom 6  
    mpier napisał:
    Jaka jest aktualna częstotliwość zegara? Jak często uruchamiane jest przerwanie? Ile trwa naciśnięcie przycisku? Musisz zmieniać opcje tylko kiedy przycisk został naciśnięty, nie przytrzymany. Dodaj do przerwania warunek sprawdzający poprzedni stan przycisku. Pomyśl nad wyeliminowaniem delay.

    Aktualna częstotliwość zegara 1MHz , przerwanie z tego co mi wyszło uruchamia się 15 razy na sekundę , z tym naciśnięciem to nie wiem ile może trwać bo różnie wychodzi , chodzi o wyelminowanie delay z podprogramów? czy to ma jakiś wpływ na niepoprawne działanie programu , mam jeszcze jedno pytanie gdyż próbowałem uruchomić ten program dla poprzedniej wersji gdzie te opcje są bardziej rozbudowane i w symulatorze wszystko działa poprawnie natomiast w rzeczywistym układzie diody zaczynaja świecic po naciśnięciu przycisku ale po ponownym naciśnięciu opcje nie przełączają się tylko program powtarza się
  • #15 18179005
    jakubajak19
    Poziom 6  
    Czy mógłby mi ktoś wyjaśnić ten kawałek kodu
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #16 18179851
    mpier
    Poziom 29  
    Narysuj sobie na kartce w kratkę trzy bajty binarnie, w jednej linii. Pierwszy krok to stan>>2 czyli dwa prawe bity pomijasz (odgradzasz kreską), a trzeci traktujesz jako pierwszy. PORTC jest ośmiobitowy, maska 0x3F pokrywa sześć pierwszych bitów od prawej. Dalej analogicznie od początku.
    Włączanie i wyłączanie PB7 nie wiem czemu służy.
    Napisz konkretnie z czym masz problem, albo próbujesz zbudować.
  • #17 18180071
    jakubajak19
    Poziom 6  
    mpier napisał:

    Napisz konkretnie z czym masz problem, albo próbujesz zbudować.

    Próbuje zbudować led cube 3x3x3 , w sumie to już zbudowałem tylko mam problem z programem , chodzi o to że chciałbym jednym button switchem zmieniać sekwencje świecenia diod , niestety nie działa to poprawnie w praktyce , program taki pierwotny z użyciem delay w symulatorze działa niestety na realnym układzie kostka włącza się po naciśnięciu switcha ale po kolejnych programy nie zmieniają się spróbowałem coś takiego jeszcze ale znów w realnym układzie nie działa
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #18 18180338
    mpier
    Poziom 29  
    Co to jest?
    jakubajak19 napisał:
    PORTD=0b00000000;

    A to?
    jakubajak19 napisał:
    PORTD=0b00000100;
    To nie może działać (chyba że przypadkiem). Skąd w ogóle pomysł pisania w taki sposób? Kilka odpowiedzi wyżej masz napisane jak powinna wyglądać prosta funkcja testująca przycisk.
  • #19 18180406
    jakubajak19
    Poziom 6  
    mpier napisał:
    Narysuj sobie na kartce w kratkę trzy bajty binarnie, w jednej linii. Pierwszy krok to stan>>2 czyli dwa prawe bity pomijasz (odgradzasz kreską), a trzeci traktujesz jako pierwszy. PORTC jest ośmiobitowy, maska 0x3F pokrywa sześć pierwszych bitów od prawej. Dalej analogicznie od początku.
    takie pytanie jeszcze do tego stan mam rozpisać jako same jednyki czy same zera ??
  • #20 18180410
    osctest1
    Poziom 21  
    @mpier to jeszcze napisz co jest złego w takim zapisie i czym się różni od:

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


    albo

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


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


    jako znawca C powiedz mi które bity PORTD zostaną ustawione tym porzypisaniem
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #21 18180434
    jakubajak19
    Poziom 6  
    mpier napisał:
    Co to jest?
    jakubajak19 napisał:
    PORTD=0b00000000;

    A to?
    jakubajak19 napisał:
    PORTD=0b00000100;
    To nie może działać (chyba że przypadkiem). Skąd w ogóle pomysł pisania w taki sposób? Kilka odpowiedzi wyżej masz napisane jak powinna wyglądać prosta funkcja testująca przycisk.
    No cóż pomysł na takie pisanie zaczerpnąłem z innego projektu takiej kostki , w sumie nie wygląda to za dobrze i chyba to zmienię tylko chciałbym wiedzieć czy to z tego powodu program nie działa w realnym układzie ?
  • #22 18180467
    osctest1
    Poziom 21  
    @jakubajak19 Moje pytanie do @mpier jest czysto retoryczne.

    Zapis jest poprawny (co nie oznacza, że Twoj progrram jest poprawny - bo go nie analizowałem), a uwagi @mpier bezsensowne. Tak że IMO ignoruj go.

    Co prawda 0b... jest rozszerzeniem standardu, ale wszystkie znane mi kompilatory implementują je.
  • #23 18180503
    jakubajak19
    Poziom 6  
    osctest1 napisał:
    @jakubajak19 Moje pytanie do @mpier jest czysto retoryczne.

    Zapis jest poprawny (co nie oznacza, że Twoj progrram jest poprawny - bo go nie analizowałem), a uwagi @mpier bezsensowne. Tak że IMO ignoruj go.

    Co prawda 0b... jest rozszerzeniem standardu, ale wszystkie znane mi kompilatory implementują je.

    Ok , a tak bez analizy mógłbyś mi powiedzieć jaki wpływ na działanie Atmegi8 mają delaye :( programy są napisane w taki sposób że ich działanie przynajmniej w symulatorze jest poprawne, w wersji rzeczywistej program uruchamia sie po wciśnieciu jak napisałem i przelatuje przez wszystkie podprogramy wszystko świeci jak ma świecić tylko nie działa to w taki sposób ze moge to przełączać
  • #24 18180514
    mpier
    Poziom 29  
    jakubajak19 napisał:
    takie pytanie jeszcze do tego stan mam rozpisać jako same jednyki czy same zera ??

    Mogą być kwadraciki.
    osctest1 napisał:
    @mpier to jeszcze napisz co jest złego w takim zapisie i czym się różni od:
    To jest złego, że wyłączasz podciąganie na pinie od przycisku włączając leda.
    osctest1 napisał:
    jako znawca C powiedz mi które bity PORTD zostaną ustawione tym porzypisaniem
    Kod: c Rozwiń Zaznacz wszystko
    PORTD=010;
    Nie jestem znawcą C, ale powiem: nieprawidłowe ;-)
  • #25 18180523
    osctest1
    Poziom 21  
    Zasada podstawowa: zadnych delay w przerwaniach. Przyjmij to na tym etapie jako aksjomat.

    Poszukaj innego sposobu.
  • Pomocny post
    #26 18184191
    szelus
    Poziom 34  
    jakubajak19 napisał:

    Ok , a tak bez analizy mógłbyś mi powiedzieć jaki wpływ na działanie Atmegi8 mają delaye :( programy są napisane w taki sposób że ich działanie przynajmniej w symulatorze jest poprawne, w wersji rzeczywistej program uruchamia sie po wciśniciu jak napisałem i przelatuje przez wszystkie podprogramy wszystko świeci jak ma świecić tylko nie działa to w taki sposób ze moge to przełączać

    Kod Ci nie działa w rzeczywistym układzie z dwóch powodów:
    I
    Tak, jak napisał @mpier, sterując LEDami wyłączasz sobie podciąganie na wejściu przycisku. W efekcie odczytujesz z tego wejścia przypadkowe zera i jedynki (wejście działa jak antena) i "cuda się dzieją". Najprostsze obejścia tego problemu w Twoim przypadku (kompletny brak struktury programu), to przeniesienie wejścia na port B albo użycie podciągnięcia (rezystora) zewnętrznego.
    II
    Kompletnie brakuje Ci eliminacji drgań styków na wejściu przycisku.
    W efekcie, po wyeliminowaniu problemu (I) naciśnięcie przycisku będzie przełączać program na przypadkowy (przeskok o kilka programów) a nie na następny. Poczytaj sobie pod pod tym linkiem jak to eliminować.

    Jeszcze inny problem jaki widzę, nie związany już z różnicami pomiędzy symulacja a rzeczywistym układem, to to, że chociaż stosujesz multipleksowane sterowanie LEDami, w programie kompletnie brak podziału na multipleksowanie i wyświetlanie wzoru. W efekcie, wprowadzanie zmian i namierzanie problemów to masakra...
  • #27 18196482
    jakubajak19
    Poziom 6  
    Dziękuje za pomoc szelus , zrobiłem jak napisałeś wszystko działa , wrzucam program gdyby ktoś miał jakieś uwagi to dajcie znać.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
REKLAMA