Brak produktów
W poprzednim artykule przedstawiłem generator PWM prosty. Prostota jest bez wątpienia jego największą zaletą, jednak ma pewną bardzo istotną wadę, która wyklucza jego zastosowanie w wielu przypadkach.
Wyobraźmy sobie, że mamy trzy odbiorniki (co wcale nie jest dużą liczbą) sterowane PWM-em prostym, tak jak na rysunku poniżej. Niech to będą silniki DC sterowane tranzystorami MOSFET. Wszystkie trzy tranzystory otwierają się w tej samej chwili, co powoduje przepływ prądu przez uzwojenia silników, a następnie po upływie pewnego czasu tranzystory się zamykają i prąd przestaje płynąć. Gdzie jest haczyk? Problem jest w tym, że wszystkie MOSFET-y otwierają się jednocześnie, co powoduje bardzo duży i nagły pobór prądu. To z kolei może powodować chwilowe spadki napięcia zasilającego, co zakłóci działanie pozostałych układów. Nie bez powodu mówi się, że PWM "sieje zakłóceniami".
Zakłócenia można znacznie zredukować, jeżeli wyjściowe przebiegi PWM poprzesuwamy w taki sposób, by w jednej chwili można było otworzyć tylko jeden tranzystor.
W generatorze PWM z korekcją fazy, licznik sterujący liczy naprzemiennie w górę i w dół. Gdy wartość graniczna (ustalająca wypełnienie) zrówna się z wartością licznika, wtedy następuje przełączenie stanu wyjścia PWM na przeciwny.
W przykładowym projekcie zrobimy cztery generatory PWM zgodnofazowe, sterowane jednym licznikiem. Powstaną zatem dwa pliki z modułami. Pierwszy zawiera sam generator PWM. Drugi z nich zawiera licznik sterujący oraz cztery instancje generatorów z pierwszego pliku.
// PLIK PWM.V module pwm( input clk, input dir, input [7:0] licznik, input [7:0] granica, output reg wyjscie = 0 ); // generator pwm always @(posedge clk) if(licznik == granica) if(!dir) wyjscie = 1; else wyjscie = 0; endmodule
Oto drugi plik z modułem nadrzędnym:
// PLIK TOP.V module generatory( input clk, input [7:0] granica1, granica2, granica3, granica4, output wyjscie1, wyjscie2, wyjscie3, wyjscie4 ); // licznik sterujący reg [7:0] licznik = 0; // licznik sterujący reg dir = 0; // kierunek liczenia always @(posedge clk) begin // zliczanie w górę lub w dół if(!dir) licznik = licznik + 1; else licznik = licznik - 1; // zmiana kierunku liczenia if(licznik == 8'hFF || licznik == 8'h00) dir = ~dir; end // instancje generatorów pwm generator1(clk, dir, licznik, granica1, wyjscie1); pwm generator2(clk, dir, licznik, granica2, wyjscie2); pwm generator3(clk, dir, licznik, granica3, wyjscie3); pwm generator4(clk, dir, licznik, granica4, wyjscie4); endmodule
I na koniec prosta procedura testowa:
// PLIK TOP_TB.V `timescale 1 us / 1 ns module top_tb; reg clk; reg [7:0] we1, we2, we3, we4; wire wy1, wy2, wy3, wy4; // instancja generatory generatory_tb( clk, we1, we2, we3, we4, wy1, wy2, wy3, wy4 ); always begin #1 clk = ~clk; end initial begin clk = 0; we1 = 8'h20; we2 = 8'h40; we3 = 8'h80; we4 = 8'hE0; #150000 $finish; end endmodule
Po przeprowadzeniu symulacji powinniśmy uzyskać taki obrazek.
I na koniec jeszcze zdjęcie z osculoskopu, na dowód, że to rzeczywiście działa :)