舵机是一种角度伺服的电机,适用于那些需要角度不断变化并可以保持的控制系统。
舵机
一个常见的舵机有三个连接线。
黑色:电源地
红色:电源(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;