Skocz do zawartości

Bardzo dziwny problem z przyciskiem


miccaldo

Pomocna odpowiedź

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

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;

*******

}

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

Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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

Link do komentarza
Share on other sites

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

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.