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

Atmega8 - Timer1 zmiana współczynnika wypełnienia

polarczn 03 Lut 2014 10:15 2280 18
REKLAMA
  • #1 13255790
    polarczn
    Poziom 16  
    Możecie rzucić okiem na ten kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Dioda podłączona do portu PB1 migami, jednak wciskanie PD5 i PD6 nie wpływa na zmianę współczynnika wypełnienia.
  • REKLAMA
  • #2 13255891
    2P
    Poziom 20  
    Nie może się zmieniać - kod wykonuje się raz i tylko raz przy rozruchu sprawdza stany przycisków. Zrób sprawdzanie przycisków w pętli. Dodatkowo znacznik, który poinformuje Cię, że przycisk był naciśnięty poprzednio, bo inaczej stan licznika będzie zmieniał się tak szybko, że nawet tego nie zauważysz. Poza tym, wypadałoby przepisać stan zmiennej a spowrotem do rejestru OCR1A.
  • REKLAMA
  • Pomocny post
    #3 13256234
    GanzConrad
    Poziom 25  
    ustaw sobie przerwanie od np. TIMER2 co 10ms i sprawdzaj 4 ostatnie stany przycisku.
    teoria:
    http://mikrokontrolery.blogspot.com/2011/02/o-drganiach-stykow-bez-bajek-przykad.html

    powyższe zaadoptowane do A8:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #4 13256450
    el2010tmp
    Poziom 25  
    Czemu ma służyć ten kod:
    polarczn napisał:
    ISR(TIMER1_OVF_vect)
    {


    PORTB|=(1<<PB1); // podciągnięcie do VCC
    }

    Tryb PWM nie wymaga "ręcznego" sterowania wyjściem.
  • #6 13264084
    polarczn
    Poziom 16  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Lekko zmodyfikowałem kod i niestety nie kompiluje się. Wiem, że trzeba będzie jeszcze dodać kod dotyczący PD7, ale na razie wyskakuje mi dużo błędów i wszystkie dotyczące kodu zaczynającego się od sei(); Jak mam rozumieć ten kod?
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #7 13264190
    BlueDraco
    Specjalista - Mikrokontrolery
    żeby zrozumieć kod, najpierw sformatuj go tak, żeby wcięcia pokazywały jego strukturę. Zgaduję, że zauważysz wtedy, że masz przynajmniej o jeden nawias zamykający za dużo.

    Zapis:
    if (wyrażenie == 0)
    zmienna = 1;
    else
    zmienna = 0;

    To to samo, co:

    zmienna = ! wyrażenie;
    - jedna linijka zamiast 8 (licząc ze zbędnymi nawiasami)...
  • #8 13265443
    GanzConrad
    Poziom 25  
    tak jak pisze poprzednik: sformatuj i napisz od nowa.
    na pierwszy rzut oka:
    - masz dwie pętle nieskończone (while(1){})
    - nie bez powodu podałem Ci odczyt stanu przycisku wewnątrz wektora przerwania (ISR(TIMER2_COMP_vect)), ponieważ polega on na odczytywaniu stanu przycisku co 10ms (przerwanie Timera)
    - Ty odczytujesz stan przycisku wewnątrz pętli głównej (co nie ma szans poprawnie zadziałać, bo nie znasz czasu obiegu tej pętli, a sposób kolegi BlueDraco polega na eliminacji drgań styków, które za zwyczaj trwają około 30ms)
    - przeczytaj artykuł z linku który Ci podrzuciłem, a wszystko się wyjaśni ;-)
  • REKLAMA
  • #9 13265643
    polarczn
    Poziom 16  
    Ten kod w STM jak na razie jest dla mnie mało przejrzysty. Nie rozumiem za bardzo co robi ten kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Załóżmy, że wcisnąłem PD5, a wcześniej wcisnąłem PD6. Czyli przechowuje to jest wartość 0X20, a ostatnia to 0X10.
    Jak zrobię przesunięcie bitowe to przechowuje zamieni się w 0x40. Czyli bitowo pierwsze zero usunąć z przodu i dopisać jedno z tyłu: 0100 0000. Operacja and z 0x40; nic nie zmienia. A operacja suma z wartością ostatnia to
    0100 0000
    0001 0000
    czyli
    0101 0000
  • #10 13266159
    BlueDraco
    Specjalista - Mikrokontrolery
    To, co nazwałeś "ostatnia" ma (a przynajmniej powinno mieć) wartość 0 lub 1, a nie 0x10. Naciśnięcie jest wykrywane wtedy, gdy zarejestrowano 3 razy przycisk zwolniony, a obecnie jest wciśnięty. W kodzie nie ma żadnego "and z 0x40".
  • #11 13276585
    polarczn
    Poziom 16  
    Kłopot w tym, że ja wcale nie rozumiem tego fragmentu kodu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    operator "&" - bitowa koniunkcja (AND), << przesunięcie bitowe. Wartość zapisana w przechowuje musi być możliwa do zapisania w formie zero jedynkowej, aby można było wykonać przesunięcie, a później koniunkcję.
  • REKLAMA
  • #12 13276683
    GanzConrad
    Poziom 25  
    Jak słusznie zauważył kolega BlueDraco, całe wyrażenie można uprościć:

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

    Timer zgłasza przerwanie co 10ms i za każdym razem sprawdza stan przycisku. Jeśli wciskasz przycisk, to na najmłodszym bicie zmiennej "Bstates" pojawia się 1, więc jeśli wartość "Bstates" będzie równa 1, czyli wystąpią 3 zera na bitach 1,2,3 oraz jedynka na bicie "0" to znaczy, że wciśnięto przycisk. Teraz po kolei:

    (Bstates << 1) & 0x0F
    "Bstaes" przesuń w lewo o jeden i zrób binarny "and" z wartością 0x0F kasując jednocześnie 4 starsze bity (interesują nas 4 poprzednie stany przycisku na 4 młodszych bitach, więc starsze bity "kasujemy")
    (!(Key_PIN & _Key)) : jak wciśniesz przycisk podłączony do masy to binarny "and" da Ci "0", więc musisz to zanegować, aby zdarzenie wciśniętego przycisku dało co wartość "1"
    (Bstates << 1) & 0x0F) | (!(Key_PIN & _Key)) : dodajesz binarnie poprzednie 3 stany przycisku z bieżącym i jeśli otrzymasz wartość 1 to znaczy, że po trzech próbkach zwolnionego przycisku, nastąpiło jego wciśnięcie.
    Ta zwykła wartość "1" mówi Ci, że przez 30ms, 4 razy odczytałeś stan przycisku i 3 odczyty dały przycisk zwolniony, a ostatni z nich dał przycisk wciśnięty.
    Jak pojawią się drgania styków to zignorujesz je ponieważ:
    1) odczytujesz przycisk co 10ms
    2) ignorujesz wszystkie przypadki poza 0001
  • #13 13276826
    BlueDraco
    Specjalista - Mikrokontrolery
    Dodajmy, że procesor nie potrafi zapisywać żadnych wartości w postaci innej niż "zerojedynkowa". ;)
  • #14 13277294
    polarczn
    Poziom 16  
    Możecie rzucić okiem na kod? Zamiast Timera 2, zastosowałem Timer0 z przerwaniem co 0,008 s. Aby uprościć kod dodałem 2 funkcje. Niestety to spowodowało, że ani dioda nie świeci, ani wyświetlacz nic nie wyświetla.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #15 13332548
    polarczn
    Poziom 16  
    Dodałem kod odpowiedzialny za pomiar temperatury z ADC (PC5) za pomocą LM335. Nóżkę V- podłączyłem do GND, V+ do VCC poprzez rezystor 10k i na tej nodze mierzę temperaturę. Wynik przy obecnym kodzie 528, a powinno być około w granicach 80-120. Czy LM335 mogło się uszkodzić?
    Lampki migają, mogę to regulować. Jednak ADC mam ciągle jedną wartość. Wydaje mi się, że program tkwi w pętli while i nie przechodzi dalej.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #16 13333636
    BlueDraco
    Specjalista - Mikrokontrolery
    Gdybym miał tak sformatowany kod, to te nie byłbym w stanie go uruchomić...

    A Twoje kolejne podstawienia różnych wartości na OCR1A nieszczególnie mają sens.
  • Pomocny post
    #17 13335547
    Tom1988p
    Poziom 16  
    Dwie nieskończone pętle while, ciekawe kiedy przejdzie z pierwszej do drugiej.
  • #18 13340368
    polarczn
    Poziom 16  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Troszkę zmieniłem kod. Zamiast pętli while zastosowałem przełącznik switch. Skoro już w Timerze2 badałem stan przycisków dodałem funkcję, która zapisuje aktualny stan przycisku do zmiennej keycode, plus wyświetlanie aktualnej wartości OCR1A na HD44780(to nie działa i do tego dojdę sam). Ale tego nie przebrnę. Czy ktoś jest w stanie poprawić ten kod?
  • #19 13340457
    BlueDraco
    Specjalista - Mikrokontrolery
    Tak, Ty jesteś w stanie go porządnie sformatować - inaczej tylko masochista będzie próbował go przeczytać i zrozumieć. Na mnie nie licz.
REKLAMA