Strony

wtorek, 27 maja 2014

Mikrokontrolery AVR - jak zacząć - wprawki w miganiu LED

Witam,

To już kolejny poradnik z cyklu "AVR jak zacząć". Tym razem pierwsze ale takie hmmm poważniejsze ćwiczenie z technik programowania dla czytelników mojej niebieskiej książki (tzw Bluebooka) .... Wiemy już bowiem jak podłączyć procka na stykówce, np ATmega8. Wiemy jak go zaprogramować, jak uruchomić do tego Eclipse, wiemy jak migać pojedynczą diodą LED .... i często na tym się kończy. My tymczasem stawiamy kolejny siedmiomilowy krok w przód .... na przykładzie zabawy diodami LED poznamy i przećwiczymy w boju kilka technik programowania. Od najprostszej niezalecanej a wręcz zakazanej ;) po inne dające mam nadzieję sporo do myślenia. Mam nadzieję, że na tym się nie zatrzymacie i sami dalej już pójdziecie jak burza, jeśli chodzi o tego typu własne ćwiczenia i pomysły. To bardzo ważne. 


zapraszam 


;)

22 komentarze:

  1. Ciekawe efekty dla początkujących, zawsze to coś innego niż jedna dioda. Super.

    PS. Drobna literówka w 00:02 sekundzie filmu :)

    OdpowiedzUsuń
    Odpowiedzi
    1. no tak ;) teraz widzę literówkę .... dzięki za uwagę ... Ale już nie uda mi się jej poprawić.

      Usuń
  2. Kolejny fajny poradnik. A teraz kilka pytań. W minucie 36:35 mówi Pan "rzutowanie do typu uint8_t, wyjaśnam to na stronie atnelowskiej..." mogę poprosić o link do tego artykułu bo, coś nie chce mi wpaść w ręce. I odnośnie samych timerów programowych. Może właśnie warto zrobić poradnik jak pozbyć się _deley_ms i zamiast tego fajnie wykorzystywać timery programowe. Pozdrawiam i czekam na więcej :)

    OdpowiedzUsuń
    Odpowiedzi
    1. odnośnie minuty: 36:35 .... to słowo klucz: "domyślna promocja do int", a odpowiedni artykuł znajduje się tutaj:

      http://atnel.pl/domyslna-promocja-do-typu-int.html

      Odnośnie timerów programowych to na pewno jeszcze i o tym będzie ;)

      Usuń
  3. Super poradnik.Więcej takich poradników.Pozdrawiam

    OdpowiedzUsuń
  4. Witam,
    Bardzo fajny poradnik Panie Mirku. Dla początkujących takich jak ja super sprawa. Może udało by się zrobić jeszcze inne efekty LED. Pewnie to nie miejsce na tego typu komentarze ale ja chciałbym zrozumieć regulację PID. Może w którymś poradniku mógłby Pan pokazać jakiś super prosty przykład z wykorzystaniem algorytmów PID i z użyciem do tego celu mikrokontrolerów. Tak żeby początkujący mogli zrozumieć jak to działa. Jeżeli nie w poradniku to może jest to jakaś podpowiedź na jeden z rozdziałów kolejnej książki:-)

    Pozdrawiam

    OdpowiedzUsuń
  5. Witaj chciałem tobie powiedzieć że twoje poradniki to nie bzdury, tylko prawdziwe wykłady i to napikowane wielką wiedzą. Odnośnie wieku to mam 63 latek i choruję na stwardnienie rozsiane i ta wiedza oraz praktyka jest dla mnie bardzo bardzo WAŻNA mój nickł "piotr"

    OdpowiedzUsuń
  6. Panie Mirku! Swietny poradnik! Po prostu uzaleznia od elektroniki ! :)

    Pozdrawiam
    Rafal

    OdpowiedzUsuń
  7. Super poradnik ,ja czekam na jakis ktory poruszy kwestie zdarzen (EVENTOW) ,nie wiem czemu ale jak czytam greenbooka to wydaje mi sie ze to jakis kosmos. Z czytaniem kodow z bb nie mam juz takich problemow. Nie wiem czy to tylko moje odczucie ,ale widac duzy przeskok w stylu pisania programow. Na plus oczywiscie dla autora ,choc ja czuje sie zostawac w tyle. :)

    OdpowiedzUsuń
    Odpowiedzi
    1. A oglądał kolega te poradniki ?

      http://mirekk36.blogspot.com/2013/04/siujemy-sie-z-callbackami-w-c.html

      http://mirekk36.blogspot.com/2013/04/encoder-avr-callbackow-ciag-dalszy-cz2.html

      i ten?

      http://mirekk36.blogspot.com/2012/12/wskazniki-struktury-callbacki-jazda-bez.html

      ale - będą jeszcze dodatkowe - będą ;)

      Usuń
  8. zaraz obejrzę ,gubię się już powoli ,jest ich tyle i ciągle nowe wychodzą :)

    OdpowiedzUsuń
  9. Bardzo interesujący poradnik, można prosić jakąś rade jak zastosować do tego typu jakiegoś taimera w celu eliminacji polecenia delay? W procedurze obsługi przerwania chyba nie powinno się zamieszczać pętli. Nie potrafię tego rozgryźć, jak ustawić flagę aby w pętli głównej czekać na tyknięcie timera i dopiero wtedy zacząć pętle for.

    OdpowiedzUsuń
  10. Udało mi się uruchomić ten program na taimerze według "projektu wielozadaniowego" jednak zamiast używać negacji taimera (!Timer1)jak w tym projekcie z książki, używam jego badanie poprzez while(Timer1);. Tylko w ten sposób działa poprawnie. Oto mój kod:
    #include
    #include
    #include
    #include

    const uint8_t tab[] PROGMEM = {0, 128, 64, 160,80, 40, 20,
    10, 5, 2, 1, 0, 1, 2, 5, 10, 20, 40, 80, 160, 64, 128};
    volatile uint8_t Timer1; /* timery programowe 100Hz */


    int main(void)
    {
    TCCR2 |= (1<<WGM21); // tryb pracy CTC
    TCCR2 |= (1<<CS22)|(1<<CS21)|(1<<CS20); // preskaler = 1024
    OCR2 = 107; // przerwanie porównania co 10ms (100Hz)
    TIMSK |= (1<<OCIE2); // Odblokowanie przerwania CompareMatch

    sei();
    DDRA = 0xff;
    PORTA = 0xff;

    while(1)
    {
    {
    uint8_t i, liczba;
    for( i=0; i<22; i++ )
    {
    Timer1 = 1;
    while(Timer1);
    liczba = pgm_read_byte( &tab[i] );
    PORTA = ~liczba;
    }
    }
    }
    }


    //procedura obsługi przerwań, timer programowy
    ISR(TIMER2_COMP_vect)
    {
    uint16_t n;
    n = Timer1; /* 100Hz Timer1 */
    if (n) Timer1 = --n;
    }

    Program steruje 8 diodami LED podłączonymi katodami do portu A.

    OdpowiedzUsuń
    Odpowiedzi
    1. Najpierw drobna uwaga odnośnie porządku w kodzie - rozkaz sei(); dajemy ZAWSZE tuż przed pętlą główną programu .... a inicjalizację przed sei(), dlatego ustawienia portu A już wie kolega jak zrobić.

      Odnośnie tego co kolega zrobił czyli while( Timer1 ); ...... to niestety (no działa to) ale jest to wręcz ZAPRZECZENIE idei programu wielozadaniowego :( ... Pomyśl teraz chwilkę

      gdy działa while( Timer1 ); .... to program główny STOI W MIEJSCU! :( ... to tak jakbyś użył dokładnie np: _delay_ms( 10 ) ....

      A chyba nie o to tu chodzi ... to co masz w książce z tym sprawdzaniem i odpalaniem timera programowego za pomocą IF() ma ogromne znaczenie ...

      dlatego że gdy timer jest > 0 to CAŁY CZAS działa sobie pętla główna, NIC jej nie blokuje - mogą się wykonywać JEDNOCZEŚNIE inne czynności. Rozumiesz teraz ? ;) już jesteś blisko

      owszem w twoim przykładzie gdy program nie robi nic innego to nie ma znaczenia - no ale teraz sobie spróbuj tak jak w książce odpalić DWA timery programowe tak aby jedna dioda migała np co 100ms a druga co 500ms. Twoją metodą z while( Timer ) ----> NIGDY się to nie uda.

      Mam nadzieję że teraz jaśniej ?

      Usuń
    2. Dziękuje za cenne uwagi:) próbowałem tak zrobić tylko jak stosuje if(!Timer1)...
      program się zawiesza nie wiem dlaczego Heh może za długo już przy tym siedze, Dziękuje za tak szybkie odpowiedzi.

      Usuń
    3. No to jak ci się zawiesza to coś musisz w środku MOCNO źle robić .... w razie czego dawaj z takimi pytaniami na forum

      www.forum.atnel.pl

      tam 100x lepiej się dyskutuje z kodem źródłowym itp - ok?

      Usuń
  11. Jasne. Bardzo dziękuje za poświęcony czas:)

    OdpowiedzUsuń
  12. A ja mam pytanko odnośnie napisania tego programu do ruchomego światełka gdy mamy diody podłączone do różnych portów???

    OdpowiedzUsuń
  13. Pytanie jest następujące, czy da się zrobić ruchome światło metodą matematyczną badz tablica jeśli diody są popdięte do różnych portów ??

    OdpowiedzUsuń
    Odpowiedzi
    1. Pewnie że się da ... tylko trzeba sprawdzać na których bitach co ma się wyświetlać i zmieniać porty

      Usuń
  14. witam, a mi się udało lampki zapalić bez rzutowania, wystarczy "tylko praca na uint8_t liczbie", /// czy to nie jest tak że "liczba" (w tym przypadku widzimy jako dziesiętna) jest przypisana do pinu jako binarna i jakby bity składowe tej liczby zapalają piny ? coś tak mi intuicja mówi ale jestem kompletnie zielony i nie wiem czy mam racje. ps uwielbiam Pana i Pana prace ;; wielki szacunek i energii do dalszej pracy życzę :) pozdrawiam wszystkich pozytywnych

    OdpowiedzUsuń