Skocz do zawartości

Trzykanałowy PWM przesuniety wzgledem siebie w fazie o 60 stopni ?


BlackJack

Pomocna odpowiedź

Mam taką zagwozdkę. Chciałbym stworzyć na mikroprocesorze 3 kanałowy PWM, ale taki aby przebieg w kolejnym kanale był przesunięty o 60 stopni w fazie względem poprzedniego. Każdy kanał regulowany oczywiście niezależnie.

CPU jakiś AVR np. ATTiny2313/Attiny861 lub PIC16F1508 (Ciekawsze MCu notabene).

Mniej więcej coś takiego

Do czego mi to potrzebne? Raczej w celach edukacyjnych i do zabawy z linką diod LED RGB. Jestem ciekaw jakie uzyskam efekty i czy taką nietypową metoda uda mi sie ograniczyć pobór prądu, a tym samym potrzebną do zasilania LEDów moc zasilacza.

Link do komentarza
Share on other sites

Tak, to typowa metoda pracy impulsowych stabilizatorów polifazowych. Zamiast jednego klucza są np. trzy pracujące z przesunięciem 120°. To pozwala na rozłożenie obciążeń poszczególnych elementów składowych w czasie (i w przestrzeni) i zmniejsza wymagania na filtry wejściowe i wyjściowe. Jak rozumiem Ty też chcesz mieć 120 a nie 60°.

Żadnej oszczędności energii tu nie uzyskasz, bo w każdym dowolnie długim okresie czasu każda "przesunięta" dioda musi zapalić się tak samo długo jakby zapalała się jednocześnie z koleżankami. Jasność średnia każdej z nich zależy jedynie od wypełnienia a to będzie takie samo w każdym układzie. Jedyne co możesz ugrać to zmniejszone zakłócenia, bo prąd pobierany z zasilacza jest bardziej "płaski". Zamiast jednego wielkiego impulsu masz trzy mniejsze.

Jeżeli podstawą czasu PWMa jest timer to jego zawartość jest taka sama dla wszystkich wyjść OCx przez niego sterowanych. Nawet Mega128 ze swoimi 3-wyjściowymi timerami nie zrobi (przy użyciu tylko jednego z nich) takiego przebiegu. Musisz zmarnować trzy timery i puścić je jednocześnie od tej samej wartości początkowej, zrobić to w sposób mieszany (programowo-sprzętowy) lub czysto programowo.

Jeżeli procesor ma robić tylko to i jest to raczej zabawa, proponuję prostą pętlę zliczającą trzy zmienne typu uint8_t, porównującą je z wartościami progowymi i odpowiednio załączającą wyjścia. Jeżeli zrobisz to w obsłudze przerwania od timera procek będzie miał jeszcze czas na coś innego. Częstotliwość przerwań np. 10kHz i zliczanie 8-bitowe wyprodukuje PWM o częstotliwości prawie 40Hz co wystarcza do oszukania oka. Procesor musisz wtedy popychać raczej szybciej niż 1MHz bo 100 instrukcji na cykl może nie wystarczyć.

Link do komentarza
Share on other sites

Tak, to typowa metoda pracy impulsowych stabilizatorów polifazowych. Zamiast jednego klucza są np. trzy pracujące z przesunięciem 120°. To pozwala na rozłożenie obciążeń poszczególnych elementów składowych w czasie (i w przestrzeni) i zmniejsza wymagania na filtry wejściowe i wyjściowe. Jak rozumiem Ty też chcesz mieć 120 a nie 60°.

Faktycznie 120° nie 60, ja sobie podzieliłem 180/3 dla tego wyszedł mi taki wynik.

Żadnej oszczędności energii tu nie uzyskasz, bo w każdym dowolnie długim okresie czasu każda "przesunięta" dioda musi zapalić się tak samo długo jakby zapalała się jednocześnie z koleżankami. Jasność średnia każdej z nich zależy jedynie od wypełnienia a to będzie takie samo w każdym układzie. Jedyne co możesz ugrać to zmniejszone zakłócenia, bo prąd pobierany z zasilacza jest bardziej "płaski". Zamiast jednego wielkiego impulsu masz trzy mniejsze.

Dokładnie o to mi chodzi o zmniejszenie prądu w impulsie, bo nie będą świecić w skrajnym przypadku wszystkie 3 LEDy naraz.

Jeżeli podstawą czasu PWMa jest timer to jego zawartość jest taka sama dla wszystkich wyjść OCx przez niego sterowanych. Nawet Mega128 ze swoimi 3-wyjściowymi timerami nie zrobi (przy użyciu tylko jednego z nich) takiego przebiegu. Musisz zmarnować trzy timery i puścić je jednocześnie od tej samej wartości początkowej, zrobić to w sposób mieszany (programowo-sprzętowy) lub czysto programowo.

Jeżeli procesor ma robić tylko to i jest to raczej zabawa, proponuję prostą pętlę zliczającą trzy zmienne typu uint8_t, porównującą je z wartościami progowymi i odpowiednio załączającą wyjścia. Jeżeli zrobisz to w obsłudze przerwania od timera procek będzie miał jeszcze czas na coś innego. Częstotliwość przerwań np. 10kHz i zliczanie 8-bitowe wyprodukuje PWM o częstotliwości prawie 40Hz co wystarcza do oszukania oka. Procesor musisz wtedy popychać raczej szybciej niż 1MHz bo 100 instrukcji na cykl może nie wystarczyć.

Niestety też nie widzę innej możliwości jak metoda pół sprzętową, co prawda ATTiny861 ma 6PWM mode w którym każdy kanał ma wejście Enable, ale to i tak nie da przebiegu który chcę uzyskać.

No nic pobawię się trochę i zobaczę co mi wyjdzie. Gdzieś leżakuje mi jeszcze AT90S2313 z czasów kiedy zaczynałem przygodę z programowaniem, postaram się wycisnąć z niego soki, a przy okazji go spożytkować. MAX taktowanie to dla niego chyba 10MHz, co powinno wystarczyć, ale ja i tak go uzbroję w 8MHz zegar po podzieleniu przez 256, to powinno dać nawet 100-120Hz odświeżania. Choć nie powiem wyzwaniem jest zrobienie tego na jak najmniejszym FOSC, bo w sumie nawet 6-7 bitowy PWM wystarczy do uzyskania ciekawej przestrzeni kolorów.

Link do komentarza
Share on other sites

Odpaliłem na szybko jakąś płyteczkę z ATmega1284. Mam tutaj kwarc 20MHz, ale wpisałem do rejestru globalnego podzielnika zegara 1/16 więc wyszło taktowanie 1.25MHz. Przy tej szybkości timer 0 z prescalerem 1/8 pracuje w trybie CTC z OCRA=8 co daje przerwania z częstotliwością ok. 17.4kHz. W przerwaniu prosta funkcja programowej generacji 3xPWM z przesunięciem 120° wykonuje się tyle, że na inne zadania zostaje jeszcze prawie 50% mocy obliczeniowej CPU. Częstotliwość powtarzania przy 8 bitach licznika wynosi 67.8Hz. Mogłoby być jeszcze z 20-30% szybciej, ale wygląda że dużo lepiej to już nie będzie.

ISR(TIMER0_COMPA_vect)
{
static uint8_t
	pwm_timer;
register uint8_t
	tmp;

LED_RED_ON;

tmp = pwm_timer++;

if (tmp < pwm0)
	PWM0_SET;
else
	PWM0_CLEAR;

tmp += 85;

if (tmp < pwm1)
	PWM1_SET;
else
	PWM1_CLEAR;

tmp += 85;

if (tmp < pwm2)
	PWM2_SET;
else
	PWM2_CLEAR;

LED_RED_OFF;
}

Zmienne pwm0, pwm1 i pwm2 to globalne poziomy wysterowania trzech kanałów:

volatile uint8_t
pwm0,
pwm1,
pwm2;

Porównania zrobiłem tak, by pwmx=0 robiło stałe zero a wyjściu. Wyjście na diodkę LED daje mi sygnał przebywania w obsłudze przerwania - widzę jak długo się wykonuje, bez wliczania prologu i epilogu ISR.

Podane przeze mnie czasy i częstotliwości możesz przeskalować sobie liniowo do własnego zegara - o ile nie zmienisz za bardzo kodu.

Stała 85 jest właśnie przesunięciem o 120° licznika modulo 256 🙂

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

Robiłem kiedyś przesunięcie o 90*, 4 kanały. Zasada podobna:

- wybierasz kilka liczników, które konfigurujesz na identyczne preskalery, wartość przepełnienia itd.

- następnie po wystartowaniu ich, przypisujesz im wartości początkowe przesunięte względem się właśnie o ten określony kąt.

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.