Skocz do zawartości

Prośba o wytlumaczenie tego zjawiska


Pomocna odpowiedź

Napisano

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


}

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

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

?

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.

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

  • 1 miesiąc później...

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