Skocz do zawartości

Pierwszy program [c]


Pomocna odpowiedź

Napisano

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

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

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.

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.

Weź pod uwagę sposób w jaki podłączyłeś diodę/przycisk, jeżeli przeanalizujesz/przedstawisz schemat zapewne wszystko się wyjaśni 🙂

Podłączenie

Atmega>>rezystor>>dioda>>masa

Atmega>>przycisk>>masa

Inne programy działają.

Zauważyłem też że jak przybliżam palec do przycisku to dioda przygasa.

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

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.

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

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