舵机 
一个常见的舵机有三个连接线。 
黑色:电源地 
红色:电源(5伏直流) 
白色:控制引脚(PWM) 
PWM控制舵机位置。伺服系统每20毫秒要有一个脉冲,以便获得正确的角度信息。脉冲宽度决定了舵机的角度运动范围。也就是说,我们可以通过发送1毫秒脉冲设置舵机到一端位置,发送2毫秒脉冲将其设置到另一个位置。 

控制波形 
我们设计一个四个输入,一个输出的模块,如下图所示 

控制模块 
Clk:时钟信号 
reset:复位信号 
button_l:用于PWM占空比的增加 
button_r:用于PWM占空比的减小 
Pwm:输出信号驱动舵机。 
首先,应该生成具有20毫秒周期的PWM信号,由于使用50MHz的时钟产生PWM,为了产生20ms信号,我们将定义一个名为counter的变量和一个名为upper的常数,它表示计数上边界。 
Upper boundary : 20ms/20ns = 1000 000 
constant upper :integer:=1000000; 
……………………….. 
process(clk,reset) 
begin 
if reset = '1' then 
pwm_reg 
counter 
duty_cycle 
elsif clk='1' and clk'event then 
pwm_reg 
counter 
duty_cycle 
end if; 
end process; 
counter_next 
控制信号占空比的值应是1毫秒至2毫秒之间。我们将定义两个常数命名dcycle_max和dcycle_min说明上下边界。 
dcycle_max:显示脉冲宽度的最大值。 
(2ms/clock period=2 ms/ 20 ns=100000) 
dcycle_min:显示脉冲宽度的最小值。 
(1ms/clock period=1 ms/ 20 ns=50000) 
脉宽(占空比)在每个PWM周期中改变,因此我们定义了一个称为tick的变量。当tick为“1”时,占空比将发生变化。 
signal tick : std_logic; 
tick 
定义了一个称为duty_in的常数,用于改变占空比。 
VHDL代码 
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 
process(clk,reset) 
begin 
if reset = '1' then 
pwm_reg 
counter 
duty_cycle 
elsif clk='1' and clk'event then 
pwm_reg 
counter 
duty_cycle 
end if; 
end process; 
counter_next 
tick 
process(button_l,button_r,tick,duty_cycle) 
begin 
duty_cycle_next 
if tick='1' then 
if button_l ='1' and duty_cycle >dcycle_min then 
duty_cycle_next 
elsif button_r ='1' and duty_cycle 
duty_cycle_next 
end if; 
end if; 
end process; 
pwm 
pwm_next 
end Behavioral;