Skocz do zawartości

Pierwszy program [c]


press2313

Pomocna odpowiedź

Witam

Zaczynam naukę języka c. Napisałem prosty program:

#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>               

int main(void)
{

DDRB |= _BV(2);
PORTB &= _BV(2);
DDRD &= _BV(7);
PORTD |=  _BV(7);

while (PIND & _BV(7))
{
PORTB |= _BV(2);
}
}

Powinien działać tak:

Jeśli pinb2 = 1 to pind7 = 1

Prosze o wyjaśnienie co namieszałem i dlaczego pinb2 nie reaguje na stan 1.

Program się pez problemu kompiluje.

Programuje w WinAVR.

Mój pierwszy temat na forum, prosze o wyrozumiałość.

Z góry dzięki

Link do komentarza
Share on other sites

Z idei kodu wynika, że jednak będzie jeśli PIND7 = 1 to PINB2 = 1, ale Twój program nie będzie działał, ponieważ nie ma pętli głównej i wykonuje się tylko raz.

Jeżeli chciałbyś, aby Twój program zadziałał należy objąć całość (oprócz DDR, ponieważ ustawienie wejść/wyjść może być wykonane jednorazowo) w pętle, np. while (1) i dodać tyldy przy negacjach &=~ .

Sugeruję nie używać "_BV" i zrobić to tak (dla przypadku jeśli PIND7 = 1 to PINB2 = 1):

int main(void) 
{ 

DDRB |= (1<<2);  // B2 jako wyjście
PORTB &=~ (1<<2);
DDRD &=~ (1<<7); // użycie tej linijki nie jest konieczne, ponieważ domyślnie piny ustawione są jako wejścia

while(1){
if (PIND & (1<<7)) 
{ 
    PORTB |= (1<<2); 
} 
else
{
    PORTB &=~ (1<<2); 
}
}

lub jeżeli chcesz zrealizować to przy pomocy tylko pętli while:

while(1){ 
 while (PIND & (1<<7)) 
 { 
    PORTB |= (1<<2); 
 } 
 PORTB &=~ (1<<2); 
}
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Bo masz odwrotnie napisane w kodzie, sprawdzasz PD7 i w zależności od niego ustawiasz PB2

Przetłumaczę napisany kod i może to pomoże Ci zrozumieć.

PB2 jako wyjście

PB2 ustawione na 0

PD7 jako wejście

PD7 włączony pullup

Jeżeli na PD7 jest 1 to ustaw na PB2 1.

Podsumowując dopóki na PD7 jest 0 to PB2 jest 0,

gdy na PD7 pojawi się 1 PB2 ustawiany jest na 1 i tak już zostaje do końca, bez względu na PD7.

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

ok.

Przed chwilą zaprogramowałem Atmege8 tak jak proponował kolega kilka postów wyżej.

PB2 - dioda

PD7 - przełącznik

int main(void) 
{ 

DDRB |= (1<<2);  // B2 jako wyjście 
PORTB &=~ (1<<2); 
DDRD &=~ (1<<7); // użycie tej linijki nie jest konieczne, ponieważ domyślnie piny ustawione są jako wejścia 

while(1){ 
if (PIND & (1<<7)) 
{ 
    PORTB |= (1<<2); 
} 
else 
{ 
    PORTB &=~ (1<<2); 
} 
}

Po włączeniu efekt następujący:

Dioda cały czas świeci.

Gdy wcisnę przycisk dioda gaśnie.

Dlaczego dioda cały czas świeci?

Po dodaniu zaprzeczenia do fragmęntu:

if (!(PIND & (2<<7)))

Dioda cały czas świeci.

Gdy wcisnę przycisk świeci mocniej.

Link do komentarza
Share on other sites

Zabrakło pull-up dla przycisku. W tym wypadku sprawdzi się kod:

int main(void) 
{ 

DDRB |= (1<<2);  // B2 jako wyjście 
PORTB &=~ (1<<2); 
DDRD &=~ (1<<7); // użycie tej linijki nie jest konieczne, ponieważ domyślnie piny ustawione są jako wejścia 
PORTD |= (1<<7); // pull-up dla przycisku (1 domyślnie, 0 gdy wciśnięty)

while(1){ 
if (PIND & (1<<7)) 
{ 
    PORTB |= (1<<2); 
} 
else 
{ 
    PORTB &=~ (1<<2); 
} 
}

Aby dioda zapalała się w momencie przyciśnięcia, należy zanegować warunek - !(PIND & (1<<7)) lub oczywiście odwrócić operacje PORTB.

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

Udało się.

#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>

int main(void) 
{
DDRB |= (1<<2);  // B2 jako wyjście 
PORTB &=~ (1<<2); 
DDRD &=~ (1<<7); // użycie tej linijki nie jest konieczne, ponieważ domyślnie piny ustawione są jako wejścia 
PORTD |= (1<<7); // pullup dla przycisku (1 domyślnie, 0 gdy wciśnięty) 

while(1)
{
if (!(PIND & (1<<7))) 

    PORTB |= (1<<2); 


else

    PORTB &=~ (1<<2); 
}
}

Taki kod zadziałał.

Wielkie dzięki.

Link do komentarza
Share on other sites

Drobna uwaga, znacznie zwiększająca czytelność kodu w szczególności po dłuższym czasie, czy dla innego programisty (który np. podpowiada Ci na forum).

Stosuj zdefiniowane nazwy pinów:

DDRB |= (1<<PB2);
PORTB &=~ (1<<PB2); 
DDRD &=~ (1<<PD7); 
PORTD |= (1<<PD7); 
itd...
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.