Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL pwm for controlling a servo

Status
Not open for further replies.

kidi3

Full Member level 1
Joined
Mar 31, 2013
Messages
98
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
2,350
I am at the moment trying to implement a PWM signal for controlling a servo motor..

The problem is though, is my PWM is not getting generated..

I don't how i managed to do it, but earlier i had an PWM up an running, but it seems something happened to the code, which doesn't not make sense..

here is it

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pwm is
   Port
      (
         CLK : in STD_LOGIC;
         PWM : out std_logic
      );
end pwm;

architecture Behavioral of pwm is
signal counter: integer range 0 to 1000000;
begin

prescaler: process(clk)
begin
if rising_edge(clk) then 
    if counter < 1000000 then 
        counter <=  counter + 1;
    else
        counter <= 0;
    end if;
end if;     
end process;

pwm_s: process(counter)
begin 
    if counter < 10000 then
        pwm <= '1';
    else 
        pwm <= '0';
    end if;
end process;
end Behavioral;

I have no idea on why it doesn't work.. Any help would be appreciated.

- - - Updated - - -

Nothing is wrong with the FPGA itself... it is the code something is wrong with.
 

I am at the moment trying to implement a PWM signal for controlling a servo motor..

The problem is though, is my PWM is not getting generated..

I don't how i managed to do it, but earlier i had an PWM up an running, but it seems something happened to the code, which doesn't not make sense..

here is it

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pwm is
   Port
      (
         CLK : in STD_LOGIC;
         PWM : out std_logic
      );
end pwm;

architecture Behavioral of pwm is
signal counter: integer range 0 to 1000000;
begin

prescaler: process(clk)
begin
if rising_edge(clk) then 
    if counter < 1000000 then 
        counter <=  counter + 1;
    else
        counter <= 0;
    end if;
end if;     
end process;

pwm_s: process(counter)
begin 
    if counter < 10000 then
        pwm <= '1';
    else 
        pwm <= '0';
    end if;
end process;
end Behavioral;

I have no idea on why it doesn't work.. Any help would be appreciated.

- - - Updated - - -

Nothing is wrong with the FPGA itself... it is the code something is wrong with.

I'm assuming that this is functionally failing since 'not getting generated' or 'it doesn't work' is rather vague. If it is something else then provide details. If functional, then read on:
- Failing in simulation or in real hardware?
- Post the testbench that you used to verify the functionality
- Based on the numbers in your code, do you realize that the PWM output has only a 1% duty cycle?

Kevin Jennings
 

The test bench does show that the code shouldn't work.. Which make no sense..

The functionality of this piece of code is to generate a PWM signal..

At moment is timing not an issue, as the issue itself is just that it doesn't generate the signal.

The hardware has been tested with an other piece of code, for which it worked.
So it must be this one..
 

The VHDL code will surely generate an 1% duty cycle pulse (not a legal servo pulse width, I presume) with fclk/1000001. In case of a 50 MHz clock, a 200 µs pulse with about 50 Hz repetition.

By using an unregistered comparator, the output will have some glitches, you may want to correct it.

No idea how you managed to get no output in your test.

It would be good practice to add signal initialization and a reset, otherwise simulation to hardware discrepancy might occur. But as far as I see not in this case.
 

What's the frequency of your system clock (CLK)?
You divide the input clock: CLK / 1000000.

You have to make sure that the result is in the range of your servo's control loop frequency.
Hobby grade servo's operate around 50Hz-400Hz.

As a side note:
When controlling a motor by an FPGA I suggest you buffer the outputs of your device or even better use an isolator IC.
Otherwise:
Nothing is wrong with the FPGA itself...
Won't be true for very long.
 

I've tested with some other code, and does seem to work with that..
 

You still haven't given enough information to help you debug your code.

Post the code that works, the clock frequency you are using for CLK, the testbench you used to check your code and then someone can possibly help you understand why your version doesn't work. As it is all the previous posters that replied have wasted their time, since you haven't posted the information that has been requested previously.
 

I'm guessing that you use an evaluation board.
Also, post it's datasheet and your pinout.
 

CLK : 50MHZ
TB:
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity pwm_tb is
end pwm_tb;

architecture Behavioral of pwm_tb is

    component pwm 
    port(
        CLK : in std_logic;
        PWM : out std_logic;
        debug_led: out std_logic
    );
    end component;
    
    signal CLK : std_logic := '0';
    signal pwm_s : std_logic := '0';
    signal debug_led : std_logic := '0';
    
    constant clk_period : time := 20ns;
begin

    uut: pwm port map(
        CLK => CLK,
        PWM => PWM_s,
        debug_led => debug_led
    );
    
    CLK_Process: process
    begin 
         CLK <= '0';
         wait for clk_period/2; 
         CLK <= '1';
         wait for clk_period/2;
    end process;

end Behavioral;

Device: xc3s50antqg144-4
 

Code:
    if counter < 10000 then
        pwm <= '1';
    else 
        pwm <= '0';
    end if;

Change 10000 to 500000.

Did you check the pinout?
Are you sure that the output levels of your board are set to 3.3V ?
 

I have checked the pinouts.. its the same as the one i been using from previous projects..
Could it possible that some setting within xilinx could have been changed?

The board provides 3.3 volt, As i've used it before for an ADC project..
 
Last edited:

I assume you also changed the position setter to 500000 ?
 

yes, no change.

- - - Updated - - -

So.. It seem like i found my error.
The program never responded to the changes i made, which was because they were never flashed to the FPGA.. => the error led were lid.. So i fiddled a bit around in the setting and bam => PWM came out.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top