docencik Napisano Sierpień 30, 2012 Udostępnij Napisano Sierpień 30, 2012 Witam wszystkich Zacznę od tego, że jestem nowy w dziedzinie mikrokontrolerów i po przeczytaniu do połowy książki Mirosława Kardasia postanowiłem za pomocą waszego kursu C dla AVR zrobić coś praktycznie. Otóż chciałem poćwiczyć ustawianie stanu wysokiego lub niskiego na jakimś pinie, które będzie sterowane za pomocą przycisku. W moim przypadku jest to pierwszy pin portu D, do którego podczepiłem diodę led. Do dwóch pierwszych pinów portu C podłączyłem przyciski. Mój problem polega na tym, że potrafię za pomocą przycisku zapalić diodę ale nie umiem już jej później zgasić. Poniżej kod mojego programiku, dwa przyciski wewnętrznie podciągnięte pod vcc zwiększają lub zmniejszają zmienną a. Jeśli zmienna a jest równa 2 dioda się pali, jeśli a jest równe 1 dioda gaśnie. Tak ja to widzę, jednak po zapaleniu diody nie chcę ona zgasnąć. Byłbym wdzięczny za wskazanie problemu. #define F_CPU 1000000L #include <avr/io.h> #include <util/delay.h> int main(void) { int a =0; DDRD |= (1<<PD0); DDRC |= (0<<PC0) | (0<<PC1); PORTC |= (1<<PC0) | (1<<PC1); while (1) { if (!(PINC & 1)) { _delay_ms(100); a= a+1; _delay_ms(100); } if (!(PINC & 2)) { _delay_ms(100); a= a-1; _delay_ms(100); } switch (a) { case 1: PORTD |= (0<<PD0); break; case 2: PORTD |= (1<<PD0); break; } } } Cytuj Link do komentarza Share on other sites More sharing options...
Harnas Sierpień 30, 2012 Udostępnij Sierpień 30, 2012 Raz : na pewno masz przycisk gaszenia dobrze podłączony? Dwa i tu jest problem. PORTD |= (0<<PD0); Operator | "dodaje" 2 bity. Jeżeli bit w rejestrze PORTD jest wyzerowany i "dodaje" się do niego jedynkę w postaci (1< I dlatego potrafisz zapalić diodę. Teraz. Mając w PORTD jedynkę i dodając do niej zero 1+0=1 dalej masz jeden. Dlatego musisz użyć operatora & w następujący sposób: PORTD &= ~(1<<PD0); Tu http://hobby.abxyz.bplaced.net/index.php?pid=4&aid=2 jest wszystko bardzo fajnie wytłumaczone w tym temacie. 1 Cytuj Link do komentarza Share on other sites More sharing options...
klonyyy Sierpień 30, 2012 Udostępnij Sierpień 30, 2012 A drgania styków wyeliminowałeś sprzętowo ? Bo w programie nic nie widzę, a w książce o tym było... Cytuj Link do komentarza Share on other sites More sharing options...
paczkaexpres Sierpień 30, 2012 Udostępnij Sierpień 30, 2012 Zrobiłeś w sumie głupi błąd zaraz go ci zaprezentuje: switch (a) { case 1: PORTD |= (0<<PD0); <--- break; case 2: PORTD |= (1<<PD0); <--- break; } } W case 2: ustawiasz PORTD_2 jako wyjście czyli w tym momencie stan portu wygląda tak: PORTD -> 0b00000001. Dioda się świeci. Następnie przechodzisz do case 1: i wykonujesz operację logiczą OR. Tylko ,że 0b00000001 OR 0 da ci znowu 0b00000001 (jeżeli nie wiesz czemu to powinieneś poczytać o operacjach logicznych). W każdym razie jeżeli chcesz ,żeby twój program działał poprawnie instrukcja z case 1: powinna wyglądać w ten sposób: PORTD &= ~(1< Do switha powinieneś dodać Defoulta ,bez tego program może zaczynać działać niepoprawnie np. gry naciśniesz 2 razy ten sam przycisk (możesz także zrobić warunek na to aby wartość a nie przekraczała zakresu <1,2>). 1 Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
Harnas Sierpień 30, 2012 Udostępnij Sierpień 30, 2012 A drgania styków wyeliminowałeś sprzętowo ? Bo w programie nic nie widzę, a w książce o tym było... To czym według ciebie jest to: _delay_ms(100); a= a+1; _delay_ms(100); ? Cytuj Link do komentarza Share on other sites More sharing options...
docencik Sierpień 30, 2012 Autor tematu Udostępnij Sierpień 30, 2012 Dzięki panowie, aż mi głupio, że taki błąd zrobiłem 😃 Drgania styków chciałem wyeliminować właśnie poprzez te delaye, nie mam pojęcia czy zrobiłem to dobrze. Cytuj Link do komentarza Share on other sites More sharing options...
klonyyy Sierpień 30, 2012 Udostępnij Sierpień 30, 2012 A drgania styków wyeliminowałeś sprzętowo ? Bo w programie nic nie widzę, a w książce o tym było... To czym według ciebie jest to: _delay_ms(100); a= a+1; _delay_ms(100); ? Może się mylę, ale zwykle po opóżnieniu sprawdza się warunek jeszcze raz - jak miało by działać takie coś ? Cytuj Link do komentarza Share on other sites More sharing options...
Bobby Sierpień 30, 2012 Udostępnij Sierpień 30, 2012 Zinkrementuje "a" tylko raz, czyli wyeliminuje kolejne drgania - działa. 1 Cytuj Link do komentarza Share on other sites More sharing options...
mirekk36 Październik 11, 2012 Udostępnij Październik 11, 2012 Szczerze polecam ten artykuł: http://mirekk36.blogspot.com/2012/10/drgania-stykow-to-bajki-wiec-jak-to.html który obala powielaną wszędzie błędną opinię na temat rzekomych efektów drgań styków oraz metod ich eliminacji. Myślę że po przeczytaniu tego - wszystko się wyjaśni. Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!