prakash_kadri
Member level 2
Hi ,
Very recently I tried to learn VHDL using some online courses. With my limited knowledge and using the help of some experts online I wrote below code.
I am using ALINIX SPARTAN 6 XILINX board and Servo KS-3527
(https://www.aliexpress.com/item/KS3...DIY-robot-robotic-arm-gimbal/32877907004.html)
My system clock is 50MHz.
Below program is to generate 64kHz from 50mHz frequency.
Below program is generate PWM pulse.In order to have a frequency of 20ms->20 * 64=1280--> which is done by implementing counter from 0 to 1279
Mapping both the above codes
Test bench:
I could able to simulate the above code and got the servo pulse as expected. But the actual servo is not working when connected to FPGA.
Servo is connected to separate 5Volt supply and control signal is connected to FPGA output pin.
Please help to rectify this issue.
Thanks.**broken link removed****broken link removed****broken link removed****broken link removed**
.
Very recently I tried to learn VHDL using some online courses. With my limited knowledge and using the help of some experts online I wrote below code.
I am using ALINIX SPARTAN 6 XILINX board and Servo KS-3527
(https://www.aliexpress.com/item/KS3...DIY-robot-robotic-arm-gimbal/32877907004.html)
My system clock is 50MHz.
Below program is to generate 64kHz from 50mHz frequency.
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ----------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity clk64kHz is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; clk_out: out STD_LOGIC ); end clk64kHz; architecture Behavioral of clk64kHz is signal temporal: STD_LOGIC; signal counter : integer range 0 to 780 := 0; begin freq_divider: process (reset, clk) begin if (reset = '1') then temporal <= '0'; counter <= 0; elsif rising_edge(clk) then if (counter = 780) then temporal <= NOT(temporal); counter <= 0; else counter <= counter + 1; end if; end if; end process; clk_out <= temporal; end Behavioral;
Below program is generate PWM pulse.In order to have a frequency of 20ms->20 * 64=1280--> which is done by implementing counter from 0 to 1279
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity servo_pwm is PORT ( clk : IN STD_LOGIC; reset : IN STD_LOGIC; -- pos : IN STD_LOGIC_VECTOR(6 downto 0); servo : OUT STD_LOGIC ); end servo_pwm; architecture Behavioral of servo_pwm is constant pos : std_logic_vector(6 downto 0):= "1111111"; ---Servo Position(pos) I kept constant just to check the program. -- Counter, from 0 to 1279. signal cnt : unsigned(10 downto 0); -- Temporal signal used to generate the PWM pulse. signal pwmi: unsigned(7 downto 0); begin -- Minimum value should be 0.5ms. pwmi <= unsigned('0' & pos) + 32; -- Counter process, from 0 to 1279. counter: process (reset, clk) begin if (reset = '1') then cnt <= (others => '0'); elsif rising_edge(clk) then if (cnt = 1279) then cnt <= (others => '0'); else cnt <= cnt + 1; end if; end if; end process; -- Output signal for the servomotor. servo <= '1' when (cnt < pwmi) else '0'; end Behavioral;
Mapping both the above codes
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity servo_pwm_clk64kHz is PORT( clk : IN STD_LOGIC; reset: IN STD_LOGIC; --pos : IN STD_LOGIC_VECTOR(6 downto 0); servo: OUT STD_LOGIC ); end servo_pwm_clk64kHz; architecture Behavioral of servo_pwm_clk64kHz is COMPONENT clk64kHz PORT( clk : in STD_LOGIC; reset : in STD_LOGIC; clk_out: out STD_LOGIC ); END COMPONENT; COMPONENT servo_pwm PORT ( clk : IN STD_LOGIC; reset : IN STD_LOGIC; --pos : IN STD_LOGIC_VECTOR(6 downto 0); servo : OUT STD_LOGIC ); END COMPONENT; signal clk_out : STD_LOGIC := '0'; begin clk64kHz_map: clk64kHz PORT MAP( clk, reset, clk_out ); servo_pwm_map: servo_pwm PORT MAP( clk_out, reset, servo ); end Behavioral;
Test bench:
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY servo_pwm_clk64kHz_tb IS END servo_pwm_clk64kHz_tb; ARCHITECTURE behavior OF servo_pwm_clk64kHz_tb IS -- Component Declaration for the Unit Under Test (UUT) COMPONENT servo_pwm_clk64kHz PORT( clk : IN std_logic; reset : IN std_logic; servo : OUT std_logic ); END COMPONENT; --Inputs signal clk : std_logic := '0'; signal reset : std_logic := '0'; --Outputs signal servo : std_logic; -- Clock period definitions constant clk_period : time := 10 ns; BEGIN -- Instantiate the Unit Under Test (UUT) uut: servo_pwm_clk64kHz PORT MAP ( clk => clk, reset => reset, servo => servo ); -- Clock process definitions clk_process :process begin clk <= '0'; wait for clk_period/2; clk <= '1'; wait for clk_period/2; end process; -- Stimulus process stim_proc: process begin -- hold reset state for 100 ns. wait for 100 ns; wait for clk_period*10; -- insert stimulus here reset <= '1'; wait for 50 ns; reset <= '0'; wait; end process; END; ---------------------
I could able to simulate the above code and got the servo pulse as expected. But the actual servo is not working when connected to FPGA.
Servo is connected to separate 5Volt supply and control signal is connected to FPGA output pin.
Please help to rectify this issue.
Thanks.**broken link removed****broken link removed****broken link removed****broken link removed**
.
Attachments
Last edited by a moderator: