代码编织梦想

一. 简介

本例将是FPGA之旅设计的第十六例,将介绍如何驱动舵机,实现任意角度的旋转,也是一个小模块,只需要三个IO即可完成驱动,一般购买模块的时候,就已经用杜邦线引出来了,根据杜邦线的颜色区分对应IO口的功能,一般由如下三种颜色组成

  • 红色 : VCC,接3.3V - 5V
  • 棕色: GND
  • 橙色: 信号IO,用于驱动舵机的旋转

请添加图片描述

二. 舵机旋转控制

控制舵机旋转也很容易,只需要给信号IO口,一定时间的高电平即可,让舵机旋转对应的角度。本例是180°的舵机。

通过下图可以看到,输入舵机信号IO的周期为20ms,根据周期内高电平的持续时间,来控制舵机旋转的角度。即0.5ms - 2.5ms 对应着 舵机的0 - 180°。了解这个后,就可以轻松的编写Verilog代码了。

请添加图片描述

三. 代码编写

一般我们的时钟频率为50Mhz,周期为20ns。

计时20ms需要1000_000个周期数

计时0.5ms需要25_000个周期数

计时2.5ms需要12_5000个周期数

为什么在这里把这几个时间所需要的周期数列举出来呢?主要是为了方便将旋转角度0-180°转换为对应的周期数。

0-180度,对应的时间为2ms,也就是100_000个周期,也就是每一度对应着555个周期。需要注意的一点是0度,对应的是25000个周期。假设旋转的度数为X,那么所需要的周期数为 X * 555 + 25000,周期数为高电平持续的时间。弄清楚这个后,通过简单的几行代码就可以完成舵机的控制了。

代码如下,

关注 公众号 回复 FPGA之旅设计99例之第十六例 获取如下代码

/*FPGA之旅		舵机驱动模块*/
module	Steering_Gear(
	
	input			sys_clk,
	input			rst_n,
	
	input			gear_req,				//舵机转动请求
	input[7:0]		angle,					//转动角度
	output			gear_ack,				//舵机转动完成

	output			gear					//舵机IO口
);


localparam	T_20ms	=		'd1000_000;//	周期20ms


reg[20:0]	T_cnt;				//	周期计时器

reg			gear_reg;

assign		gear		=	gear_reg;
assign		gear_ack	= ( T_cnt == T_20ms ) ? 1'b1 : 1'b0;

//周期计数
always@(posedge	sys_clk or negedge rst_n )
begin
	if( rst_n == 1'b0 )
		T_cnt <= 'd0;
	else if( gear_ack == 1'b1 )
		T_cnt <= 'd0;
	else if( gear_req == 1'b1 )
		T_cnt <= T_cnt + 1'b1;
	else
		T_cnt <= 'd0;	
end


//脉冲输出
always@(posedge sys_clk or negedge rst_n)
begin
	if( rst_n == 1'b0 )
		gear_reg <= 1'b0;
	else if( gear_req == 1'b1 && T_cnt < ( angle * 'd555 + 'd2500) )
		gear_reg <= 1'b1;
	else
		gear_reg <= 1'b0;
end

endmodule 
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44678052/article/details/127139635

FPGA_Verilog学习之旅(5)---FPGA驱动舵机-爱代码爱编程

话不多说,这次直接贴完整版代码,三个按键分别控制 舵机左偏、右偏、来回摆动 module servo( input sys_clk_50, input sys_rst_n , input key1 , input key2 , input key3 , output reg pwm_ou