Skocz do zawartości

Obsluga klawisza w atm328p w C


Krawi92

Pomocna odpowiedź

Witam, 2 dzień męczę się z pozornie prostym zadaniem. Otóż chcę, po wciśnięciu switcha zapalić diodę, a jak puszcze to ma się zgasić. Nie wiem, gdzie jest mój błąd w rozumowaniu,w kodzie.

pod PB0 podłączyłem microswitch do masy, a do PD1 LED. Po załadowaniu programu dioda świeci się cały czas, nie reaguje na przycisk jakby procek widzial ciągle stan niski na PB0.


 


#include <avr/io.h>
#include <util/delay.h>


int main (){
DDRB &=~(1<<0); // Ustawiam PB0 jakos wejscie
DDRD |= (1<<1); // Ustawiam PD1 jako wyjscie
PORTB |= (1<<0); // Podciagam wew. rezystorem do vcc switch

if (!(PINB & (1<<0))) { // Jesli odczytana wartosc PB0 to 0
PORTD |= (1<<1); // Zapal diode na PD1
}else{ // jesli jest inaczej
PORTD &=~(1<<1); // Zgas diode na PD1
}
}

Co ciekawe zauwazylem, ze wgrywajac program kilka razy pod rząd dioda raz świeci, raz nie świeci, jest to losowe

Edytowano przez Krawi92
Link do komentarza
Share on other sites

Twój program nawet jeśli był dobrze napisany to wykona się tak szybko że tego nie zauważysz 😉 Poza tym ustawienia bitów lepiej napisać tak:

DDRB&=~(1<<PB0)

gdyż od razu widać co gdzie się ustawia. Co do programu: po resecie wszystkie piny są wejściami z bez podciągania więc należy je włączyć

PORTB|=(1<<PB0)

Cały program mógłby wyglądać tak:

#include <avr/io.h>
#include <util/delay.h>


int main (){
//DDRB &=~(1<<0); // Ustawiam PB0 jakos wejscie
DDRD |= (1<<PD1); // Ustawiam PD1 jako wyjscie
PORTB |= (1<<PB0); // Podciagam wew. rezystorem do vcc switch

  
for(;;){  //PĘTLA!
if (!(PINB & (1<<0))) { // Jesli odczytana wartosc PB0 to 0
PORTD |= (1<<PD1); // Zapal diode na PD1
}else{ // jesli jest inaczej
PORTD &=~(1<<PD1); // Zgas diode na PD1
}
}
}

 

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

Jezu, wrzuciłem do pętli while(1) i działa... Wczoraj też miałem program w pętli ale coś mi nie działało i się zakręciłem tak że szok... Spróbuje teraz od nowa napisać po staremu, ponieważ teraz do obsługi przycisku wykorzystałem odrębny port, bo jak robiłem wszystko na porcie D to nie działało, ale sprobuje ponownie. 😉 

Na 1 porcie też teraz działa... Kamień spadł z serca 😄

#include <avr/io.h>
#include <util/delay.h>


int main (){
DDRD &=~(1<<PD0);
DDRD |=(1<<PD1);
PORTD |= (1<<PD0);
while (1){
	if (!(PIND &(1<<PD0))) {
		PORTD |= (1<<PD1);
	}else{
		PORTD &=~(1<<PD1);
	}
}
}

 

Edytowano przez Krawi92
Link do komentarza
Share on other sites

Warto korzystać z makr #define wtedy łatwo jest podmieniać piny i porty tylko trzeba na początku troszkę się napracować np:


#define LEDPORT PORTD
#define LEDPIN (1<<PD1)
#define LEDTOG LEDPORT^= LEDPIN
#define LEDON LEDPORT|=LEDPIN 
#define LEDOFF LEDPORT&=~LEDPIN
  
#define SWPIN (1<<PB0)
#define SWDOWN !(PINB & SWPIN)
  
int main(){
 
  DDRD|=LEDPIN;
  PORTB|=SWPIN;
  
  

Ale później masz ułatwione manipulacje na pinach

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 zapis taki dla portu DDRx bedzie ok ?

DDRx |= 0bxxxxxxxx

I tu z góry ustawiam co wejscie co wyjscie. Sprawdzałem i działa tylko myśle, jakie mogą byc komplikacje w innych przypadkach. Większość ludzi pisze, żeby przesuwać bity. Niektórzy nawet wpisują hexy, z tym że nie są one dla mnie tak czytelne jak zapis binarny... 

Link do komentarza
Share on other sites

To jest dobre do czasu... aż zapomnisz co gdzie chciałeś ustawić bądź wyzerować w przypadku portu IO w zakresie jednego rejestru np DDR sprawa jest dość prosta bo bity ustalają tylko wejście bądź wyjście. A co np: z takim rejestrem timera? Ot timer2 ma rejestr TCCR2B powiedz mi który zapis jest jaśniejszy:

TCCR2B |= 0b00000101;

Czy

TCCR2B|= (1<<CS22)|(1<<CS20);

Pamiętać trzeba że być może będziesz chciał wrócić do swojego programu po jakimś czasie, wg mnie lepiej od razu widzieć co się ustawiało niż szukać po nocie katalogowej który bit za co odpowiada. 

  • Lubię! 1
Link do komentarza
Share on other sites

No juz rozumiem, faktycznie dla prostych rejestrów I/O to czytelniej stosować zapis binarny. A jesli chodzi o timer to faktycznie, czytelniej jest bo widać, który bit włączam. Myślę, że jak pójde bardziej do przodu i zaczne operować na innych rejestrach niż I/O to różnica będzie dostrzegalna. 

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.