FPGA Center



 * Project Introduction

  * VHDL Code

VHDL CODE

PWM Generator

First, we should genarate a PWM signal that has 20 ms period.

Since our developer board has 50 MHz’lik (20 ns)clk , we use 50 MHz clock for generation of PWM. In order to produce a 20 ms signal we will define a variable named counter and a constant  named upper which indicate upper boundary.

Then we evalute the upper boundary.

Upper boundary : 20ms/20ns = 1000 000

constant upper :integer:=1000000;
………………………..

process(clk,reset)
    begin
       if reset = '1' then
           pwm_reg<='0';
           counter<=0;
           duty_cycle<=0;
       elsif clk='1' and clk'event then
           pwm_reg<=pwm_next;
           counter<=counter_next;
          duty_cycle<=duty_cycle_next;
      end if;
end process;

counter_next<= 0 when counter = period else
                            counter+1;


Controlling The Duty Cycle

The values of Duty Cycle of control signal should be between 1 ms and 2 ms. So we will define two constans named dcycle_max and dcycle_min which indicate down and upper boundares respectively.

Pulse width (Duty Cycle) is changed in period of PWM. So we define a variable called tick. When tick is "1", duty cycle will change.

signal tick:std_logic;
………………………
tick<= '1' when counter= 0 else
'0';

We also define a constant called Duty_in to show how fast the motor rotates.



Controlling The Speed of Servomotor Rotation

In this project we defined the speed of motor rotation that motion takes 5 ms to complete one cycle.

By using the following equation:

Motor Speed(s) = ((dcycle_max- dcycle_min)*period) / duty_in

We will get the following result:

Duty_in= ((100000-50000)*20 ms)/5 s= 200


Whole Code

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity servo_pwm is
    Port ( clk           : in  STD_LOGIC;
               reset      : in  STD_LOGIC;
               button_l : in  STD_LOGIC; 
               button_r : in  STD_LOGIC;
               pwm       : out  STD_LOGIC);
   end servo_pwm;

architecture Behavioral of servo_pwm is
      constant period:integer:=1000000;
      constant dcycle_max:integer:=100000;
      constant dcycle_min:integer:=50000;
      constant duty_in:integer:=200;
      signal pwm_reg,pwm_next:std_logic;
      signal duty_cycle,duty_cycle_next:integer:=0;
      signal counter,counter_next:integer:=0;
      signal tick:std_logic;
    begin
    --register
         process(clk,reset)
              begin
                   if reset = '1' then
                        pwm_reg<='0';
                        counter<=0;
                        duty_cycle<=0;
                   elsif clk='1' and clk'event then
                         pwm_reg<=pwm_next;
                         counter<=counter_next;
                         duty_cycle<=duty_cycle_next;
                   end if;
             end process;

counter_next<= 0 when counter = period else
                           counter+1;
tick<= '1' when counter= 0 else
             '0';

--Changing Duty Cycle
   process(button_l,button_r,tick,duty_cycle)
        begin
             duty_cycle_next<=duty_cycle;
              if tick='1' then
                   if button_l ='1' and duty_cycle >dcycle_min then
                          duty_cycle_next<=duty_cycle-duty_in;
                   elsif button_r ='1' and duty_cycle < dcycle_max then
                          duty_cycle_next<=duty_cycle+duty_in;
                  end if;             
            end if;                           
      end process;
--Buffer
pwm<=pwm_reg;    
pwm_next<= '1' when counter < duty_cycle else
                         '0';   
end Behavioral;

Test Bench                                                                                                                                    

 

Home | Fpga | VHDL | VHDL Dictionary | Digital Design | Simulation | PCB | Examples | Contact Us
Copyright © 2010 - 2013 FPGAcenter. All Rights Reserved.