日常·唠嗑: 2020已经过去,回首这一年,真的经历了很多,申报项目、集创赛、电赛、机械创新赛、挑战杯、写博客、遇见她……一路走来磕磕碰碰,也成长了许多。在2021伊始,写下这篇博客博客,希望能不忘初心,也希望每个人能越来越好,心想事成。
前言
我的大创项目,广东科技基金项目申报的都是关于水陆两栖的作品,动力装置难免需要用到风力推进,普通电机体积大,转速慢,基本无法满足需求。经过研究,我发现无人机使用的无刷电机就可以符合这些要求,降低整个作品的重量,还能提供充足的动力。从去年11月,我就一直在想做一下无刷电机的程序控制,但是由于很多事堆积在一起,每次看一下就放弃了,没去深入研究。最近总算下定决心解决这一问题了,在网上基本找不到FPGA控制无刷电机的相关资料(就连单片机控制无刷电机的程序都很难找到),在这里我将自己最近的学习所得在这里分享给大家。先看一下我做的作品效果视频:
基于FPGA:电调与无刷电机控制
一、什么是电调、无刷电机
1、电调
电调又称电子调速器,指的是根据控制信号调节电动机的转速。电调的连接一般是和输入线和电池连接,电调的输出线与电机连接,电调的信号线与接收机连接。电调最主要是用在航模、车模、船模、飞碟以及飞盘的玩具模型上面,这些模型可以通过电调驱动电机完成的各种的指令,达到与真实一样的效果。
关于电调的控制信号(重点): 电调信号是pwm信号,信号频率为50HZ,一个周期为20ms。对于电调来讲, 高电平脉宽为1ms表示停转(低于1ms的时候电机会发出滴滴的声音),高电平脉宽为2ms表示满油门运转(可以调整周期时间来控制转速,范围为1ms~2ms); 注: 其实无刷电机的驱动方式跟舵机一模一样。对于舵机来说1.5ms是归中,1ms和2ms分别为左右满舵。值得一提的是,电调有双向以及单向的,双向的可以通过程序控制电机正反转,双向电调1ms的时候,为电机满速反转。单向电调,无刷电机三根线与电调三根线接即可,接线方式任意,若发现电机旋转方向相反,只要调整上述三根的任意两根线即可。电调与舵机的pwm驱动时序图:
2、无刷电机
电机参数: KV额定值为1000,可以使用2S,3S或4S LiPo电池供电,并且需要30A ESC。 无刷电动机的KV额定值定义了无负载时每伏电动机的RPM。在这种情况下,1000KV意味着,例如,如果我们为电动机提供2S锂电池,其电压为7.4伏,则电动机的最大RPM可以达到1000的7.4倍,即7400 RPM。无刷电机非常耗电,最常用的供电方法是使用锂聚合物电池。 LiPo电池的“ S”号表示该电池有多少个电池,每个电池的电压为3.7V。在实验中,我使用的是3S LiPo电池,该电池具有3节电池且为11.1V。因此,我可以预期我的电机将达到11100的最大RPM。
最后,在实验中要使用的20A电调,它可以满足电动机的要求。 ESC的一侧有3条线,用于控制电动机的三相,而另一侧则有2条线,为信号线和GND,用于接收开发板的pwm信号和共地。 注: 有些电调这一侧是有三根线的,一根为信号线,另外两根为+5V和GND用来给开发板供电。我使用的这款是没办法通过电调给开发板供电的,需要另开接电源给开发板供电。
二、如何接线
图片中,电调ESC一侧三个口接电机三根线(随便接,没有顺序),另外一侧,有4根线(有一些电调是5根,多出来一根可以给开发板供电),红线(粗),黑线(粗)接电池正负极,白线(细)接开发板pwm引脚,黑线接开发板GND共地。
三、 程序驱动
1、FPGA程序(Verilog)
module red_run(
sys_clk,
sys_rst_n,
data, //data为控制信号输入,这里我用的是红外遥控来控制转速,你们可以把它改成开发板按键控制就好了
pwm_out);
input sys_clk;
input sys_rst_n;
input [7:0] data;
output pwm_out;
wire sys_clk;
wire sys_rst_n;
wire [7:0] data;
reg pwm_out;
parameter s=1000_000,//20ms-----T
s0=125_000,//2.5ms----180
s1=100_000,//2ms-----135
s2=75_000,//1.5ms----90
s3=50_000,//1ms-----45
s4=25_000;//0.5ms---0
s5=60_000,
reg [15:0] period_cnt ; //1khz 1ms 1ms/20ns=50000
reg [31:0] cnt_r;
reg [31:0] cnt;
always@(*)begin
if(!sys_rst_n)begin
cnt_r <= 31'd0;
end
else
case(data)
8'd22: cnt_r <= s4;
8'd25: cnt_r <= s3;
8'd13: cnt_r <= s2;
8'd12: cnt_r <= s1;
8'd24: cnt_r <= s0;
8'd94: cnt_r <= s5;
default:begin
cnt_r <= s3;
end
endcase
end
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
cnt <= 31'd0;
else if(cnt >= s)
cnt <= 31'd0;
else
cnt <= cnt + 1'b1;
end
always@(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
pwm_out <= 1'b0;
else if(cnt <= cnt_r)
pwm_out <= 1'b1;
else
pwm_out <= 1'b0;
end
endmodule //red_run
2、Arduino程序(C)
#include<Servo.h>
Servo ESC; //Servo函数用来产生pwm信号
int poLValue;
void setup(){
//ALLach the ESC on pin 9
ESC.attach(9,1000,2000); //(pin,min pulse width,max pulse width in)
}
void loop(){
potValue - analogRead(A0);
poLValue - map(poLValue,0,1023,0,180);
ESC.write(potValue);
}
总结
去年三月份申请的大创,一直等到现在才动手第一步,后面要再努力点了。文章有许多东西可能不是很严谨,后面再查阅相关资料进行修改补充,也希望每个学习的人一起提出来,一起完善文章,谢谢。