Skocz do zawartości

[C] Sterowanie silnikami przez PWM


ps19

Pomocna odpowiedź

Mam problem, otóż chcę wysterować 2 silniki przez PWM, kręci się tylko 1 (OC1A) ,a OC1B stoi w miejscu.Wina na 99% nie leży po stronie sprzętu gdyż moge normalnie włączyć silnik poprzez podanie stanu wysokiego na pin.

int main(void) {

               DDRD |= _BV(PD5) | _BV(PD4);
               TCCR1A =(_BV(COM1A1) | _BV(COM1B1));

                TCCR1A |= _BV(CS10); //PWM z korekcja fazy, preskaler 1
                TCCR1B |= _BV(WGM10); //PWM z korekcja fazy, preskaler 1
                        OCR1A=150;
               	 OCR1B=150;
               	}

__________

Komentarz dodany przez: Treker

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

Elvis - mam tą pętle tyle że nie skopiowałem całego programu.

Treker - nie mam oscyloskopu, ale chyba nie zauważyłeś, że mostki są zmostkowane, więc steruje tylko jednym kanałem.Na PD3 nie wygeneruje PWM co najwyżej przerwanie.

Z moich wcześniejszych testów wynika, że muszę w przypadku mostka dolnego sygnał podawać na PD4, a w przypadku mostka górnego na PD5.

Kod testowy (działa):

//silnik 1 - wejscia
#define AIN1_1 PB3
#define AIN2_1 PB0
#define BIN1_1 PB1
#define BIN2_1 PB2

//silnik 2 - wejscia
#define AIN1_2 PC5
#define AIN2_2 PC4
#define BIN1_2 PC6
#define BIN2_2 PC7

#define PWM_A1 PD4
#define PWM_B1 PD3
#define PWM_A2 PD5
#define PWM_B2 PD6
#define PRAWY_TYL PORTB |= (1<<AIN2_1); PORTD |= (1<<PWM_A1);
#define PRAWY_PRZOD PORTB |= (1<<AIN1_1);// PORTD |= (1<<PWM_A1);
#define PRAWY_STOP PORTB &= ~(1<<AIN2_1); //PORTD &= ~(1<<PWM_A1)
#define LEWY_TYL PORTC |= (1<<AIN1_2); PORTD |= (1<<PWM_A2);
#define LEWY_PRZOD PORTC |= (1<<AIN2_2); PORTD |= (1<<PWM_A2);
#define LEWY_STOP PORTC &= ~(1<<AIN2_2); //PORTD &= ~(1<<PWM_A2);

int main(void)
{
while(1)
{
PRAWY_TYL;
_delay_ms(1000);
PRAWY_STOP;
}
}

Link do komentarza
Share on other sites

piotreks-89, Raczej tego nie naprawie bez nowego projektu płytki, uszkodzone punkty lutownicze przy mostku naprawione drucikami, zalane klejem na gorąco (Brak środków finansowych), ale jak na razie zależy mi bardziej na działaniu niż na wydajności prądowej.

Link do komentarza
Share on other sites

Faktycznie nie zauważyłem, że masz połączone kanały, ale to nie zmienia tego, że wtedy na oba powinieneś podawać sygnał PWM-u. Nie rozumiem w jakim celu mieszałeś w to piny nie będące wyjściami PWM-ów.

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

Jak podaje na 1 też działa, ale pomińmy problemy z mostkowaniem. Zależy mi na podaniu sygnału PWM na PD4, aby drugi silnik też się obracał.

Link do komentarza
Share on other sites

TCCR1A |= _BV(CS10); //PWM z korekcja fazy, preskaler 1 
TCCR1B |= _BV(WGM10); //PWM z korekcja fazy, preskaler 1

Te ustawienia są złe. Sprawdź w jakich rejestrach znajdują się bity CS10 i WGM10. A i B na końcu tych rejestrów nie oznacza wcale, że są to osobne ustawienia dla wyjścia A i B - a mam wrażenie, że tak to zrozumiałeś.

To powinno iść mniej więcej tak:

	//Konfiguracja PWM
TCCR1A |= (1<<WGM10); //Fast PWM 8bit
TCCR1B |= (1<<WGM12); //Fast PWM 8bit
TCCR1B |= (1<<CS10) | (1<<CS11); //Preskaler 64
TCCR1A |= (1<<COM1A1) | (1<<COM1B1); //Clear down

OCR1A = 0;
OCR1B = 0;
  • Lubię! 1
Link do komentarza
Share on other sites

No dobra, niby 3 razy sprawdzałeś, to czemu nie zauważyłeś, że ustawiasz bity:

CS10 w TCCR1A

WGM10 w TCCR1B

Skoro według dokumentacji M32, strony 105 i 108:

CS10 jest w TCCR1B

WGM10 jest w TCCR1A

No chyba, że mam złą wersję noty.

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

Płytka zmostkowana, tyle że nie działa lewy silnik, a prawy obraca się tylko w jedną stronę.

Kod na razie prosty do sprawdzenia czy wszystko działa:

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

//silnik 1 (LEWY) - wejscia
#define BIN1_1 PB1
#define AIN2_1 PB0

//silnik 2 (PRAWY) - wejscia
#define AIN1_2 PC5
#define BIN2_2 PC7

//silniki - pwm
#define PWM_A1 PD4
#define PWM_A2 PD5

uint8_t i;
#define PRAWY_PRZOD PORTC |= (1<<BIN2_2); PORTD |= (1<<PWM_A1);
#define PRAWY_TYL PORTC |= (1<<AIN1_2); PORTD |= (1<<PWM_A1);
#define PRAWY_STOP PORTC &= ~(1<<BIN2_2); PORTD &= ~(1<<PWM_A1)
#define LEWY_TYL PORTB |= (1<<BIN1_1); PORTD |= (1<<PWM_A2);
#define LEWY_PRZOD PORTB |= (1<<AIN2_1); PORTD |= (1<<PWM_A2);
#define LEWY_STOP PORTB &= ~(1<<AIN2_1); PORTD &= ~(1<<PWM_A2);

int main(void) {
DDRB |= (1<<BIN1_1) | (1<<AIN2_1);
DDRC |= (1<<AIN1_2) | (1<<BIN2_2);
DDRD |= (1<<PWM_A1) | (1<<PWM_A2);

while(1) {
LEWY_TYL;
_delay_ms(1000);
LEWY_STOP;
_delay_ms(1000);
LEWY_PRZOD;
_delay_ms(1000);
PRAWY_TYL;
_delay_ms(1000);
PRAWY_STOP;
_delay_ms(1000);
PRAWY_PRZOD;
	}
}

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.