Skocz do zawartości

Prośba o wytlumaczenie tego zjawiska


docencik

Pomocna odpowiedź

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;
			}
	}	


}
Link do komentarza
Share on other sites

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.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

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>).

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

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); 

?

Link do komentarza
Share on other sites

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ś ?

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.