Forum Discussion
how to fix varying pwm along with constant frequency of 20kHz in cyclon 2 ep2c5t144c8
Hi! I am using ALTERA cyclon 2 ep2c5t144c8n board for generating varying pulse width modulation (duty cycle from 0 to 100%) along with constant frequency of 20kHz. I have written the code and its working well but the problem is that the varying pwm is running very fast on oscilloscope due to which I cannot see the proper pattern of varying pwm. The other problem is about frequency that I want constant frequencyof 20kHz with varying pwm but its also varying like first it goes down to 10kHz then comes up at 18kHz then at 20kHz and this process repeats again and again....in short we can say that random values of frequency is generating....How can I fix this problem??? Please help me out, your answers will be highly appreciable! Thank you...!
8 Replies
- Altera_Forum
Honored Contributor
You need to give us more to work with. It's something wrong with your design - for which you've not given us any detail. How is your design captured? Verilog? VHDL? Schematic? Post your design and we may be able to help.
Cheers, Alex - Altera_Forum
Honored Contributor
thanks for your response alex!
its VHDL I have the written VHDL code with me... what do you mean by design?? I am not getting about it!!! if I send you the output waveform would it be helpfull for you to understand? - Altera_Forum
Honored Contributor
Your 'design' is what you want your device to do. Sounds like you've written it in VHDL. Post your VHDL code (your design) to this post and we can probably help.
Does it work in simulation? Cheers, AlexPlease wrap any code in 'CODE'' (#) tags - Altera_Forum
Honored Contributor
Code:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity pwm_sti is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; feed_back : in STD_LOGIC_VECTOR (7 downto 0); driv1_out : out STD_LOGIC; driv2_out : out STD_LOGIC; pwm_out : out STD_LOGIC); end pwm_sti; architecture Behavioral of pwm_sti is signal counter_166, counter_166_delay : unsigned(7 downto 0); signal count_2500clk_cycles : unsigned(11 downto 0); signal pwm_comp_reg : unsigned(11 downto 0); signal count_pwm_comp_reg : unsigned(11 downto 0); signal delta_reg : unsigned(7 downto 0); signal driv1_out_sig, driv2_out_sig, state_falg : std_logic; signal counter_1div60_div4, counter_1div60_div4_delay : unsigned(1 downto 0); begin driv1_out <= driv1_out_sig; driv2_out <= driv2_out_sig; -- pwm generation process process(clk) variable pwm_comp_var : unsigned(12 downto 0); begin if(clk'event and clk = '1')then if(reset = '1') then counter_166 <= (others => '0'); counter_166_delay <= (others => '0'); count_2500clk_cycles <= (others => '0'); pwm_comp_reg <= (others => '0'); count_pwm_comp_reg <= (others => '0'); delta_reg <= (others => '0'); driv1_out_sig <= '1'; driv2_out_sig <= '0'; counter_1div60_div4 <= (others => '0'); counter_1div60_div4_delay <= (others => '0'); state_falg <= '0'; else pwm_out <= '0'; if(state_falg = '0') then delta_reg <= unsigned (feed_back); state_falg <= '1'; else if(count_2500clk_cycles = "100111000100") then count_2500clk_cycles <= (others => '0'); counter_166 <= counter_166 + 1; -- adding value to pwm comp reg if(counter_1div60_div4(0) = '0') then pwm_comp_var := resize(pwm_comp_reg, 13) + resize(delta_reg, 13); pwm_comp_reg <= pwm_comp_var(11 downto 0); elsif(counter_1div60_div4(0) = '1') then pwm_comp_var := resize(pwm_comp_reg, 13) - resize(delta_reg, 13); pwm_comp_reg <= pwm_comp_var(11 downto 0); end if; -- after half sine cycle if(counter_166 = "10100110") then counter_166 <= (others => '0'); driv1_out_sig <= not (driv1_out_sig); driv2_out_sig <= not (driv2_out_sig); pwm_comp_reg <= (others => '0'); end if; elsif(count_2500clk_cycles = "100111000011") then count_pwm_comp_reg <= (others => '0'); count_2500clk_cycles <= count_2500clk_cycles + 1; else count_2500clk_cycles <= count_2500clk_cycles + 1; if(count_pwm_comp_reg <= pwm_comp_reg) then count_pwm_comp_reg <= count_pwm_comp_reg + 1; pwm_out <= '1'; end if;-- count_pwm_comp end if; -- 2500clk -- creating a delay counter_166_delay <= counter_166; if ((counter_166 = "01010011" and counter_166_delay = "01010010") or (counter_166 = "10100110" and counter_166_delay = "10100101")) then counter_1div60_div4 <= counter_1div60_div4 + 1; end if;-- counter_166 -- creating a delay counter_1div60_div4_delay <= counter_1div60_div4; if(counter_1div60_div4 = "00" and counter_1div60_div4_delay = "11") then delta_reg <= unsigned (feed_back); end if; --counter 1 div 60 div 4 end if; -- state falg end if; --reset end if; -- clk end process end Behavioral; - Altera_Forum
Honored Contributor
Yes it works in simulation now I am trying to implement this code on my hardware but I am facing problem which I have discussed above!
- Altera_Forum
Honored Contributor
I don't want to put you off your code but I can't follow it since I have my own simple code below for pwd at any duty cycle, any frequency:
library ieee; use ieee.std_logic_1164.all; use IEEE.numeric_std.all; entity pwm is port( clk : in std_logic; freq_word : in std_logic_vector(13 downto 0) := "00011001100110"; duty_scaled : in std_logic_vector(13 downto 0) := "10000000000000"; pwm : out std_logic ); end entity; architecture rtl of pwm is signal ptr : unsigned(14 downto 0) := (others => '0'); begin process(clk) begin if(rising_edge(clk)) then ptr <= ptr + unsigned(freq_word); pwm <= '0'; if ptr(13 downto 0) < unsigned(duty_scaled) then pwm <= '1'; end if; end if; end process; end rtl; - Altera_Forum
Honored Contributor
Thank you kaz! I hope your code would help me...
- Altera_Forum
Honored Contributor
Over complicated though your code is it behaves exactly the same in simulation as it does on my dev board. I can see the same varying PWM pattern on my scope as I see in simulation. The fixed frequency outputs behave as well and don't move around as you suggested in your first post.
So, I can only assume you're having trouble with your oscilloscope and seeing what you expect. Cheers, Alex