PWM (Pulse Witdh Modulation) yani Darbe Genişlik Modülasyonu, oranının değiştirilebildiği sinyal modülasyondur. oranı Duty Cycle olarak adlandırılır ve ile ifade edilir. Aşağıda bir PWM sinyali görülmektedir.
ortalama değer olmak üzere duty cycle oranının değişmesi ile sinyalin ortalama değeri değişir:
Bu sayede sinyalin gerilimini değiştirmeden yük üzerinde harcanan ortalama güç ayarlanmış olur.
FPGA üzerinde PWM sinyal üretebilmek için ve kontrol değişkenlerimiz olsun. Bu ve değişkenleri aşağıdaki gibi tanımlanmış olsun:
Tasarımın VHDL kodu:
--Kütüphaneler library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; entity PWM_Module is port(Clk : in std_logic; --Clk Girişi A, B : in std_logic_vector(15 downto 0); --Kontrol Girişleri --PWM Frekansı = Clk / A --Duty Cycle = 1 - B / A PWMOut : out std_logic); --PWM Çıkışı end PWM_Module; architecture Behavioral of PWM_Module is begin --PWM Sinyalinin Üretildiği Process process(Clk, A, B) variable ClkCnt : unsigned(15 downto 0) := (others => '0'); begin if rising_edge(Clk) then --ClkCnt, A'dan küçük ise ClkCnt değerini 1 arttır if ClkCnt < unsigned(A) then ClkCnt := ClkCnt + 1; --Değil ise sıfırla else ClkCnt := (others => '0'); end if; end if; --ClkCnt, B'den küçük ise PWMOut'a '0' ata if ClkCnt < unsigned(B) then PWMOut <= '0'; --Değil ise '1' ata else PWMOut <= '1'; end if; end process; end Behavioral;
Quartus II programı tarafından oluşturulan RTL şeması:
PWM ile Led Parlaklık Kontrolü
VHDL kodu:
--Kütüphaneler library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; entity PWM_Led is port(Clk : in std_logic; --Clk Girişi Led : out std_logic_vector(15 downto 0)); --Led çıkışı end PWM_Led; architecture Behavioral of PWM_Led is --PWM komponentinin çağrılması component PWM_Module port(Clk : in std_logic; --Clk Girişi A, B : in std_logic_vector(15 downto 0); --Kontrol Girişleri --PWM Frekansı = Clk / A --Duty Cycle = 1 - B / A PWMOut : out std_logic); --PWM Çıkışı end component; signal PWMOut : std_logic; signal B : std_logic_vector(15 downto 0) := (others => '0'); begin --PWM komponenti --PWM freknası 50Mhz / 0x01F4 = 100khz PWM : PWM_Module port map(Clk, X"01F4", B, PWMOut); process(Clk) variable ClkCnt : integer range 0 to 250000 := 0; variable YukariAsagi : boolean := true; begin --100khz çıkışlı clock bölücü if rising_edge(Clk) then if ClkCnt < 249999 then ClkCnt := ClkCnt + 1; else ClkCnt := 0; --YukarıAsagi değişkeni true ise B sinyalinin değerini 1 arttır if YukariAsagi then B <= std_logic_vector(unsigned(B) + 1); --False ise 1 azalt else B <= std_logic_vector(unsigned(B) - 1); end if; end if; --Duty cycle %10 ile %80 arasında değişmekte if unsigned(B) > 449 then YukariAsagi := false; elsif unsigned(B) < 101 then YukariAsagi := true; end if; end if; end process; --Bütün ledleri PWMOut sinyaline bağla Leds : for i in 0 to 15 generate Led(i) <= PWMOut; end generate; end Behavioral;
Video:
Sanırım bölümün elektronik haberleme 🙂 FPGA eğitimine nereden nasık başladın bu konuda bilgi verebilir misin ?
Bölümüm Elektrik-Elektronik. FPGA'ya uzun zamandır başlamak istemişimdir. Kitlerin fiyatlarında dolayı bu yılın başında ilk FPGA kitimi alabildim. Kiti aldığımdan beri çeşitli projeler yaparak kendimi geliştiriyorum.