话不多说,这次直接贴完整版代码,三个按键分别控制 舵机左偏、右偏、来回摆动
module servo(
input sys_clk_50,
input sys_rst_n ,
input key1 ,
input key2 ,
input key3 ,
output reg pwm_out // PWM输出
);
// parameter define
parameter TIME_20MS = 20'd1_000_000 ;
parameter TIME_0MS5 = 20'd25_000 ;
parameter TIME_1MS = 20'd50_000 ;
parameter TIME_1MS5 = 20'd75_000 ;
parameter TIME_2MS = 20'd100_000 ;
parameter TIME_2MS5 = 20'd125_000 ;
parameter TIME_SWING = 25'd10_000_000;
// reg define
reg [19:0] pwm_cnt;
reg [19:0] pwm_sel;
reg key1_d0;
reg key1_d1;
reg key2_d0;
reg key2_d1;
reg key3_d0;
reg key3_d1;
reg [24:0] swing_cnt;
reg swing_en;
reg swing_flag;
// wire define
wire key1_flag;
wire key2_flag;
wire key3_flag;
// 按键检测
assign key1_flag = (~key1_d0) & key1_d1;
always @(posedge sys_clk_50 or negedge sys_rst_n)
begin
if(!sys_rst_n) begin
key1_d0 <= 1'b1;
key1_d1 <= 1'b1;
end
else begin
key1_d0 <= key1 ;
key1_d1 <= key1_d0;
end
end
assign key2_flag = (~key2_d0) & key2_d1;
always @(posedge sys_clk_50 or negedge sys_rst_n)
begin
if(!sys_rst_n) begin
key2_d0 <= 1'b1;
key2_d1 <= 1'b1;
end
else begin
key2_d0 <= key2 ;
key2_d1 <= key2_d0;
end
end
assign key3_flag = (~key3_d0) & key3_d1;
always @(posedge sys_clk_50 or negedge sys_rst_n)
begin
if(!sys_rst_n) begin
key3_d0 <= 1'b1;
key3_d1 <= 1'b1;
end
else begin
key3_d0 <= key3 ;
key3_d1 <= key3_d0;
end
end
// 选择转动角度
always @(posedge sys_clk_50 or negedge sys_rst_n)
begin
if(!sys_rst_n) begin
pwm_sel <= TIME_1MS5; // 复位处于1.5ms高脉冲状态
swing_en <= 1'b0;
end
else if((key1_flag == 1'b1) && (key2_flag == 1'b0) && (key3_flag == 1'b0)) begin
swing_en <= 1'b0;
pwm_sel <= TIME_0MS5;
end
else if((key1_flag == 1'b0) && (key2_flag == 1'b0) && (key3_flag == 1'b1)) begin
swing_en <= 1'b0;
pwm_sel <= TIME_2MS5;
end
else if(((key1_flag == 1'b0) && (key2_flag == 1'b1) && (key3_flag == 1'b0)) || (swing_en == 1'b1)) begin
swing_en <= 1'b1;
if(swing_flag == 1'b0)
pwm_sel <= TIME_1MS;
else
pwm_sel <= TIME_2MS;
end
end
// PWM周期计数_20ms
always @(posedge sys_clk_50 or negedge sys_rst_n)
begin
if(!sys_rst_n)
pwm_cnt <= 20'd0;
else if(pwm_cnt == TIME_20MS - 1'b1)
pwm_cnt <= 20'd0;
else
pwm_cnt <= pwm_cnt + 1'b1;
end
// 循环计数0.2s,标志位翻转
always @(posedge sys_clk_50 or negedge sys_rst_n)
begin
if(!sys_rst_n)
swing_cnt <= 25'd0;
else if((swing_cnt == TIME_SWING - 1'b1) || (key2_flag == 1'b1))
swing_cnt <= 25'd0;
else
swing_cnt <= swing_cnt + 1'b1;
end
always @(posedge sys_clk_50 or negedge sys_rst_n)
begin
if(!sys_rst_n)
swing_flag <= 1'b0;
else if(swing_cnt == TIME_SWING - 1'b1)
swing_flag <= ~swing_flag;
end
// PWM输出
always @(posedge sys_clk_50 or negedge sys_rst_n)
begin
if(!sys_rst_n)
pwm_out <= 1'b0;
else if(pwm_cnt <= pwm_sel - 1'b1)
pwm_out <= 1'b1;
else
pwm_out <= 1'b0;
end
endmodule