miccaldo Napisano Listopad 18, 2012 Udostępnij Napisano Listopad 18, 2012 Witam, mam coś czego kompletnie nie rozumiem, otóż mam 2 przyciski i silnik podłączony do mostka l293d, chcę aby po naciśnięciu drugiego przycisku kręcił się silnik, ale silnik w ogóle nie reaguje na przycisk, kręci się sam bez naciścięcia. Ale co jest dziwne: w tym samym kodzie, tylko z innym przyciskiem tylko na innym pinie normalnie działa! I o co tu chodzi? Oto kod z pierwszym przyciskiem, działa prawidłowo: #define F_CPU 1000000L #include <avr/io.h> #include <util/delay.h> void pwm_init() { TCCR1A |= (1<<WGM10) | (1<<COM1A1) | (1<<COM1B1); // timer 1 TCCR1B |= (1<<WGM12) | (1<<CS10); DDRB |= (1<<PB1) | (1<<PB2); // output pwm } void init() { DDRD |= (1<<PD0) | (1<<PD1); // motor 1 PORTD |= (1<<PD1) | (1<<PD0); PORTD |= (1<<PD3);// switch 1 DDRD |= (1<<PD3); } int main(void) { pwm_init(); init(); while(1) { if(PIND & 0x08) { PORTD |= (1<<PD0); PORTD &= ~(1<<PD1); OCR1A = 190; } } } Program z innym przyciskiem, nie działa: #define F_CPU 1000000L #include <avr/io.h> #include <util/delay.h> void pwm_init() { TCCR1A |= (1<<WGM10) | (1<<COM1A1) | (1<<COM1B1); // timer 1 TCCR1B |= (1<<WGM12) | (1<<CS10); DDRB |= (1<<PB1) | (1<<PB2); // output pwm } void init() { DDRD |= (1<<PD0) | (1<<PD1); // motor 1 PORTD |= (1<<PD1) | (1<<PD0); PORTB |= (1<<PB6);// switch 2 DDRB |= (1<<PB6); } int main(void) { pwm_init(); init(); while(1) { if(PINB & 0x40) { PORTD |= (1<<PD0); PORTD &= ~(1<<PD1); OCR1A = 190; } } } Jak widać zmieniam tutaj tylko konfiguracje przycisku, więc na moje oko wszystko powinno działać tak samo, a w drugim przypadku jak pisałem wcześniej silnik kręci się sam nie reagując na przycisk. Proszę o wyjaśnienie co jest nie w porządku. Pozdrawiam. Cytuj Link do komentarza Share on other sites More sharing options...
sosnus Listopad 18, 2012 Udostępnij Listopad 18, 2012 Może przez przypadek na stałe zwarłeś PB6 z masą. To jest na płytce stykowej czy na własnoręcznie wytrawionej płytce. Jeżeli na własnej, to pokaż spód płytki, może coś to pomoże. [ Dodano: 18-11-2012, 20:40 ] EDIT: Mógłbyś dać więcej komentarzy, oraz jakieś makrodefinicje, by poprawić czytelność kodu. [ Dodano: 18-11-2012, 20:44 ] EDIT: I jeszcze jedno. Złap multimetrem oba piny switcha, i zobacz, czy nie ma tam zwarcia. Cytuj Link do komentarza Share on other sites More sharing options...
miccaldo Listopad 20, 2012 Autor tematu Udostępnij Listopad 20, 2012 Układ mam na płytce stykowej. Chciał bym aby po naciśnięciu pierwszego przycisku zaczął chodzić silnik o wypełnieniu pwm 170, a z każdym naciśnięciem drugiego przycisku pwm zwiększał by się o 20, jednak działa to w ten sposób że po naciśnięciu pierwszego, silnik chodzi przy pwm 170, ale na drugi przycisk już nie reaguje, albo przy naciśnięciu drugiego przycisku chodzi z pwm=190. Co zmienić w kodzie żeby działało poprawnie? #define F_CPU 1000000L #include <avr/io.h> #include <util/delay.h> void pwm_init() { TCCR1A |= (1<<WGM10) | (1<<COM1A1); // timer 1 TCCR1B |= (1<<WGM12) | (1<<CS10); DDRB |= (1<<PB1); // output pwm } void init() { DDRD |= (1<<PD0)|(1<<PD1); // motor 1 PORTD |= (1<<PD1) | (1<<PD0); PORTD |= (1<<PB3);//przycisk 1 PORTB |= (1<<PB6);// przycisk 2 DDRD &= ~(1<<PD3);// przycisk 1 z podciągnięciem do Vcc DDRB &= ~(1<<PB6);// przycisk 2 z podciągnięciem do Vcc } int main(void) { pwm_init(); init(); int i; uint8_t predkosc; predkosc = 170; while(1) { for(i=0;i<5;i++); { if(!(PIND & 0x08)) // jesli pierwszy przycisk { PORTD |= (1<<PD0); PORTD &= ~(1<<PD1); OCR1A = predkosc; } else if(!(PINB & 0x40)) // jesli drugi przycisk { if(predkosc >= 170) { PORTD |= (1<<PD0); PORTD &= ~(1<<PD1); predkosc += 20; } } } } } Proszę o pomoc Cytuj Link do komentarza Share on other sites More sharing options...
sosnus Listopad 20, 2012 Udostępnij Listopad 20, 2012 Zrób wcięcia w kodzie, będzie czytelniejszy. Dlaczego nie zrobiłeś makrodefinicji OCR1A? Wtedy byłoby łatwiej i czytelniej. "OCR1A = predkosc; " no ale to chyba się dzieje tylko w tym miejscu w kodzie. A zobacz co się stanie jeżeli zamiast gwiazdek wstawisz '' OCR1A = predkosc ; '' if(predkosc >= 170) { PORTD |= (1< PORTD &= ~(1< predkosc += 20; ******* } Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
miccaldo Listopad 20, 2012 Autor tematu Udostępnij Listopad 20, 2012 Ok, wykombinowałem coś takiego: #define F_CPU 1000000L #include <avr/io.h> #include <util/delay.h> void pwm_init() { TCCR1A |= (1<<WGM10) | (1<<COM1A1); // timer 1 TCCR1B |= (1<<WGM12) | (1<<CS10); DDRB |= (1<<PB1) | (1<<PB2); // output pwm } void init() { DDRD |= (1<<PD0)|(1<<PD1); // motor 1 PORTD |= (1<<PD1) | (1<<PD0); PORTD |= (1<<PB3);//przycisk 1 PORTB |= (1<<PB6);// przycisk 2 DDRD &= ~(1<<PD3);// przycisk 1 z podciągnięciem do Vcc DDRB &= ~(1<<PB6);// przycisk 2 z podciągnięciem do Vcc } int main(void) { pwm_init(); init(); uint8_t predkosc; predkosc = 170; while(1) { if(!(PIND & 0x08)) // jesli pierwszy przycisk { PORTD |= (1<<PD0); PORTD &= ~(1<<PD1); OCR1A = predkosc; if(!(PINB & 0x40)) // jesli drugi przycisk { if(predkosc = 170) { PORTD |= (1<<PD0); PORTD &= ~(1<<PD1); predkosc += 20; OCR1A = predkosc; } } } } } Działa prawie dobrze, z początku drugi przycisk nie działa, trzeba wcisnąć pierwszy, kręci się nie z pełną mocą, a po naciśnięciu drugiego przycisku kręci się szybciej, tylko że działa to tylko raz:) a ja chciał bym żeby za każdym razem nabierał prędkości, co w tym wypadku należało by zmienić? Myślę że jakaś lekka poprawka i będzie ok. Cytuj Link do komentarza Share on other sites More sharing options...
sosnus Listopad 20, 2012 Udostępnij Listopad 20, 2012 if(predkosc = 170) { PORTD |= (1< PORTD &= ~(1< predkosc += 20; OCR1A = predkosc; } Za drugim razem prędkość masz już równą 190 a nie 170, tak? Więc warunek nie spełniony, i instrukcje wewnątrz " if(predkosc = 170) " nie są wykonywane Cytuj Link do komentarza Share on other sites More sharing options...
miccaldo Listopad 20, 2012 Autor tematu Udostępnij Listopad 20, 2012 Owszem, tylko kiedy zmieniłem znak z '=', na '>=', również nie działało, a powinno także coś tu jest nie tak. Cytuj Link do komentarza Share on other sites More sharing options...
sosnus Listopad 20, 2012 Udostępnij Listopad 20, 2012 Teraz przyjżałem się jeszcze raz. Zrobiłeś podstawowy błąd. if(predkosc = 170) Ty nie PORÓWNUJESZ, tylko nadajesz zmiennej prędkość wartość 170. (Aby porównać powinieneś dać znak ==) W ogóle potrzebujesz ten warunek: if(predkosc == 170) ? Powtarzam, zrób wcięcia w kodzie, będzie O WIELE CZYTELNIEJ. Cytuj Link do komentarza Share on other sites More sharing options...
miccaldo Listopad 20, 2012 Autor tematu Udostępnij Listopad 20, 2012 Uczę się c++ jedynie przez internet i serdeczną pomoc użytkowników forum, także obawiam się że podstawowe problemy nękać mnie będą jeszcze przez długi czas:) ale cieszę się że jest jakiś postęp. No cóż, popróbuje z tym jutro. Dziękuję za odpowiedź, napiszę jeśli coś będzie nie tak. Cytuj Link do komentarza Share on other sites More sharing options...
miccaldo Listopad 24, 2012 Autor tematu Udostępnij Listopad 24, 2012 Ok, działa już zwiększanie prędkości podczas naciśnięcia przycisku drugiego, jednak chciałbym aby przycisk 3 z kolei zmniejszał prędkość, napisałem taki kod: #define F_CPU 1000000L #include <avr/io.h> #include <util/delay.h> #define silnik_lewo PORT #define _BV(bit) (1 << (bit)) void pwm_init() { TCCR1A |= (1<<WGM10) | (1<<COM1A1); // timer 1 TCCR1B |= (1<<WGM12) | (1<<CS10); DDRB |= _BV(1) | _BV(2); // output pwm } void init() { DDRD |= _BV(0)| _BV(1); // motor 1 PORTD |= _BV(1) | _BV(0); PORTD |= _BV(3);//przycisk 1 PORTB |= _BV(6);// przycisk 2 PORTD |= _BV(7);//przycisk 3 DDRD &= ~_BV(3);// przycisk 1 z podciągnięciem do Vcc DDRB &= ~_BV(6);// przycisk 2 z podciągnięciem do Vcc DDRD &= ~_BV(7);// przycisk 3 z podciągnięciem do Vcc } int main(void) { pwm_init(); init(); uint8_t predkosc; predkosc = 170; while(1) { if(!(PIND & 0x08)) // jesli pierwszy przycisk { PORTD |= _BV(0); PORTD &= ~_BV(1); OCR1A = predkosc; _delay_ms(80); if(!(PINB & 0x40)) // jesli drugi przycisk { predkosc += 10; if(predkosc>240) predkosc = 170; _delay_ms(80); if(!(PIND & 80)) { predkosc -= 10; _delay_ms(80); } } } } } Wzorowałem się na tej stronie: http://mikrokontrolery.blogspot.com/2011/02/if-warunkowa-instrukcja-sterujaca.html Tylko właśnie obawiam się że jeśli warunek 2 mam spełniony, to warunku 3 program nie bierze pod uwagę, próbowałem różnymi sposobami ale nie wychodzi. Proszę o wyjaśnienie co tu jest nie tak. Pozdrawiam. Cytuj Link do komentarza Share on other sites More sharing options...
kling Listopad 24, 2012 Udostępnij Listopad 24, 2012 Z tego co widzę, to sprawdzasz 3 warunek tylko wtedy kiedy drugi jest spełniony, a drugi warunek sprawdzasz tylko wtedy kiedy pierwszy jest spełniony. Chyba nie taka była Twoja intencja;) Przyprzyj się dokładnie gdzie otwierasz a gdzie zamykasz klamry 'bloków' if. Cytuj Link do komentarza Share on other sites More sharing options...
miccaldo Listopad 24, 2012 Autor tematu Udostępnij Listopad 24, 2012 A dało by się zrobić, aby funkcja if działała niezależnie od tego, czy powyższy warunek jest spełniony, czy też nie? Cytuj Link do komentarza Share on other sites More sharing options...
kling Listopad 24, 2012 Udostępnij Listopad 24, 2012 #define F_CPU 1000000L #include <avr/io.h> #include <util/delay.h> #define silnik_lewo PORT #define _BV(bit) (1 << (bit)) void pwm_init() { TCCR1A |= (1<<WGM10) | (1<<COM1A1); // timer 1 TCCR1B |= (1<<WGM12) | (1<<CS10); DDRB |= _BV(1) | _BV(2); // output pwm } void init() { DDRD |= _BV(0)| _BV(1); // motor 1 PORTD |= _BV(1) | _BV(0); PORTD |= _BV(3);//przycisk 1 PORTB |= _BV(6);// przycisk 2 PORTD |= _BV(7);//przycisk 3 DDRD &= ~_BV(3);// przycisk 1 z podciągnięciem do Vcc DDRB &= ~_BV(6);// przycisk 2 z podciągnięciem do Vcc DDRD &= ~_BV(7);// przycisk 3 z podciągnięciem do Vcc } int main(void) { pwm_init(); init(); uint8_t predkosc; predkosc = 170; while(1) { if(!(PIND & 0x08)) // jesli pierwszy przycisk { //klamra otwiera 1 ifa PORTD |= _BV(0); PORTD &= ~_BV(1); OCR1A = predkosc; _delay_ms(80); }//zamyka 1 ifa if(!(PINB & 0x40)) // jesli drugi przycisk { //otwiera drugiego ifa predkosc += 10; if(predkosc>240) predkosc = 170; _delay_ms(80); }//zamyka drugiego ifa if(!(PIND & 80)) { //otwiera 3 ifa predkosc -= 10; _delay_ms(80); } //zamyka 3 ifa } //zamyka while } //zamyka main Teraz program sprawdzi Ci w pętli głównej wszystkie trzy warunki zaczynając od pierwszego, zupełnie nie zależnie. Cytuj Link do komentarza Share on other sites More sharing options...
miccaldo Listopad 24, 2012 Autor tematu Udostępnij Listopad 24, 2012 Już próbowałem tak wcześniej, ale niestety nie reaguje na 3 przycisk, chociaż on działa bo sprawdzałem. Ten program zatrzymuje się przy drugim if'ie. Spróbowałem z break;, w ten sposób: if(predkosc>240) break; teraz silnik się rozpędza do wysokich obrotów i nie reaguje na nic, chyba wychodzi z pętli także to zły pomysł jest. [ Dodano: 24-11-2012, 16:07 ] Tutaj np. idealnie działa podobny program: http://mnowator.pl/tag/sterowanie-jasnoscia-diody-led-przez-pwm/ ale jakoś nie mogę dojść do tego, może ta funkcja return 0 coś zmieni? Albo spróbować coś z else if... Cytuj Link do komentarza Share on other sites More sharing options...
kling Listopad 25, 2012 Udostępnij Listopad 25, 2012 if(!(PIND & 80)) if(!(PIND & 0x80)) 80 = 0x50 😉 0x80 = 128 😉 Proste błędy jest najtrudniej znaleźć😉 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!