Skocz do zawartości

[C] Sterowanie silnikami przez PWM


Pomocna odpowiedź

Napisano

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

Przecież PWM generowany jest na pinach PD5 oraz PD4, a Twoje podłączenie "PWM" do mostka to PD4 i PD3. Więc błąd w sprzęcie niestety masz 😉

  • Lubię! 1

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;
}
}

ps19, skoro zmostkowałeś kanały układów, aby uzyskać większy prąd na wyjściu, to i piny sterujące kanałami powinny być sparowane! PWMA z PWMB, AIN1 z BIN1, AIN2 z BIN2 i tak w przypadku obu układów.

  • Lubię! 1

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.

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

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

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

Przeciez to jest to samo tylko, że teraz jest tryb Fast PWM, a u mnie PWM with Phase Correct.

W 16 bitowych timer/counter1

tak dalej tylko 1 silnik działa - ten sam co wcześniej

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

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;
	}
}

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