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
;)
Ciekawe efekty dla początkujących, zawsze to coś innego niż jedna dioda. Super.
OdpowiedzUsuńPS. Drobna literówka w 00:02 sekundzie filmu :)
no tak ;) teraz widzę literówkę .... dzięki za uwagę ... Ale już nie uda mi się jej poprawić.
Usuń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ńodnośnie minuty: 36:35 .... to słowo klucz: "domyślna promocja do int", a odpowiedni artykuł znajduje się tutaj:
Usuńhttp://atnel.pl/domyslna-promocja-do-typu-int.html
Odnośnie timerów programowych to na pewno jeszcze i o tym będzie ;)
Super poradnik.Więcej takich poradników.Pozdrawiam
OdpowiedzUsuńWitam,
OdpowiedzUsuń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
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ńPanie Mirku! Swietny poradnik! Po prostu uzaleznia od elektroniki ! :)
OdpowiedzUsuńPozdrawiam
Rafal
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ńA oglądał kolega te poradniki ?
Usuń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ą ;)
zaraz obejrzę ,gubię się już powoli ,jest ich tyle i ciągle nowe wychodzą :)
OdpowiedzUsuń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ń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:
OdpowiedzUsuń#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.
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ć.
Usuń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 ?
Dziękuje za cenne uwagi:) próbowałem tak zrobić tylko jak stosuje if(!Timer1)...
Usuńprogram się zawiesza nie wiem dlaczego Heh może za długo już przy tym siedze, Dziękuje za tak szybkie odpowiedzi.
No to jak ci się zawiesza to coś musisz w środku MOCNO źle robić .... w razie czego dawaj z takimi pytaniami na forum
Usuńwww.forum.atnel.pl
tam 100x lepiej się dyskutuje z kodem źródłowym itp - ok?
Jasne. Bardzo dziękuje za poświęcony czas:)
OdpowiedzUsuńA ja mam pytanko odnośnie napisania tego programu do ruchomego światełka gdy mamy diody podłączone do różnych portów???
OdpowiedzUsuńNo i gdzie to pytanie ?
Usuń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ńPewnie że się da ... tylko trzeba sprawdzać na których bitach co ma się wyświetlać i zmieniać porty
Usuń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ń