fpga做的电调开源原理图和代码求大神协助解决问题。
本帖最后由 mikeyaosemiac 于 2015-6-10 18:11 编辑先上视频http://v.youku.com/v_show/id_XMTI1OTQ2MzU2MA==.html
电路图
现在问题是噪音巨大而且电流也很大,似乎有许多换相是错误的。我把我的代码贴上来希望大神能够帮忙看一眼哪里有错误
整体算法是下桥PWM,PWM低电平同步比较器采样,换相后7.5度开始检测过零,过零后15度执行换相(0-30度都试过,不好使)
下面是自动换向器模块的代码
module auto_commutator_sydelay(ac_clk,ac_en,ac_rst,ac_01a,ac_01b,ac_01c,ac_10a,ac_10b,ac_10c,ac_phase
);
input ac_clk,ac_en,ac_rst,ac_01a,ac_01b,ac_01c,ac_10a,ac_10b,ac_10c;//输入的信号来自过零检测模块,分别代表a,b,c比较器输出发生0->1或者1->0的变化
output ac_phase;
reg ac_phase;
reg count_flag;
reg count;
reg demag_count;
wire count_zero;
assign count_zero=(count<11);
parameter
P_0=0,
P_1=1,
P_2=2,
P_3=3,
P_4=4,
P_5=5,
P_6=6,
P_1d=7,
P_2d=8,
P_3d=9,
P_4d=10,
P_5d=11,
P_6d=12;
reg state,next_state;
always @(ac_01b or ac_01c or ac_10a or ac_10b or ac_10c or ac_en or count_zero)//@(ac_a or ac_b or ac_c or ac_en or count_zero)\\检测到过零事件或者等待换相事件到达
begin
next_state=16'b0;
case(1'b1)
state:begin
if(ac_en)
begin
next_state=1'b1;
ac_phase=1;
// count_flag=0;
end
else
begin
next_state=1'b1;
ac_phase=0;
end
end
state:begin
if((ac_01c==1)&&(count>demag_count))\\当比较器发生跳变且距离上一次换相已经大于7.5电角度时过零事件有效(利用7.5电角度来屏蔽消磁)
begin
next_state=1'b1;
demag_count<=(count>>2);
ac_phase=1;
end
else
begin
next_state=1'b1;
ac_phase=1;
end
end
state:begin//过零后等待等待时间到达,执行换相,这里等待的是15电角度(其他值也是不好),很奇怪。
if(count_zero)
begin
next_state=1'b1;
ac_phase=2;
end
else
begin
next_state=1'b1;
ac_phase=1;
end
end
state:begin
if((ac_10b==1)&&(count>demag_count))
begin
demag_count<=(count>>2);
next_state=1'b1;
ac_phase=2;
end
else
begin
next_state=1'b1;
ac_phase=2;
end
end
state:begin
if(count_zero)
begin
next_state=1'b1;
ac_phase=3;
end
else
begin
next_state=1'b1;
ac_phase=2;
end
end
state:begin
if((ac_01a==1)&&(count>demag_count))
begin
demag_count<=(count>>2);
next_state=1'b1;
ac_phase=3;
end
else
begin
next_state=1'b1;
ac_phase=3;
end
end
state:begin
if(count_zero)
begin
next_state=1'b1;
ac_phase=4;
end
else
begin
next_state=1'b1;
ac_phase=3;
end
end
state:begin
if((ac_10c==1)&&(count>demag_count))
begin
demag_count<=(count>>2);
next_state=1'b1;
ac_phase=4;
end
else
begin
next_state=1'b1;
ac_phase=4;
end
end
state:begin
if(count_zero)
begin
next_state=1'b1;
ac_phase=5;
end
else
begin
next_state=1'b1;
ac_phase=4;
end
end
state:begin
if((ac_01b==1)&&(count>demag_count))
begin
demag_count<=(count>>2);
next_state=1'b1;
ac_phase=5;
end
else
begin
next_state=1'b1;
ac_phase=5;
end
end
state:begin
if(count_zero)
begin
next_state=1'b1;
ac_phase=6;
end
else
begin
next_state=1'b1;
ac_phase=5;
end
end
state:begin
if((ac_10a==1)&&(count>demag_count))
begin
demag_count<=(count>>2);
next_state=1'b1;
ac_phase=6;
end
else
begin
next_state=1'b1;
ac_phase=6;
end
end
state:begin
if(count_zero)
begin
next_state=1'b1;
ac_phase=1;
end
else
begin
next_state=1'b1;
ac_phase=6;
end
end
default:begin
next_state=1'b1;
ac_phase=0;
end
endcase
end
always @(negedge ac_rst or posedge ac_clk)
begin
if (!ac_rst)
begin
state <= (1'b1 << P_0) ;
count<=0;
end
else
begin
state <=(next_state) ;
if((state==1)||(state==1)||(state==1)||(state==1)||(state==1)||(state==1))//计算一个从换相到下一次过零的时间用于过零后到下一次换相的延时
begin
count<=count+1;
end
else if((state==1)||(state==1)||(state==1)||(state==1)||(state==1)||(state==1)) //计算一个从换相到下一次过零的时间用于过零后到下一次换相的延时
begin
count<=count-2;
end
end
end
endmodule
过零探测模块
module zero_detector(zd_clk,zd_rst,zd_in,zd_sync,zd_01out,zd_10out
);
input zd_clk,zd_rst,zd_in,zd_sync;
output zd_01out;
wire zd_01out;
output zd_10out;
wire zd_10out;
reg zd_state_now;
reg c_state;
reg filter_buf;
assign zd_10out=zd_state_now&(!zd_state_now);
assign zd_01out=zd_state_now&(!zd_state_now);//zd_state_now^zd_state_now;
always @(posedge zd_clk,negedge zd_rst)
begin
zd_state_now<={zd_state_now,c_state};
if(!zd_rst)
begin
zd_state_now<=0;
end
else
begin
if(filter_buf==0)
begin
c_state<=0;
end
else if(filter_buf==3)//检测到两个0或两个1的读数则认为此时读数为0或1
begin
c_state<=1;
end
end
end
always @(posedge zd_sync)
begin
filter_buf<={filter_buf,zd_in};//同步的采样。每次在PWM为低电平即将翻转成高电平之前会到来zd_sync
end
endmodule
驱动桥模块,下桥PWM
module bridge_driver(bridge_rst,bridge_clk,bridge_pwm_in,a_up,b_up,c_up,bridge_ah,bridge_al,bridge_bh,bridge_bl,bridge_ch,bridge_cl,bridge_phase
);
input bridge_rst,bridge_clk,bridge_pwm_in,a_up,b_up,c_up;
input bridge_phase;
output bridge_ah,bridge_al,bridge_bh,bridge_bl,bridge_ch,bridge_cl;
reg bridge_ah,bridge_al,bridge_bh,bridge_bl,bridge_ch,bridge_cl;
always @ (posedge bridge_clk or negedge bridge_rst)
begin
if(!bridge_rst)
begin
bridge_ah<=1;
bridge_al<=0;
bridge_bh<=1;
bridge_bl<=0;
bridge_ch<=1;
bridge_cl<=0;
end
else
begin
case(bridge_phase)
0:begin
bridge_ah<=1;
bridge_al<=0;
bridge_bh<=1;
bridge_bl<=0;
bridge_ch<=1;
bridge_cl<=0;
end
1:begin
bridge_ah<=0;//(!((!a_up)|bridge_pwm_in));
bridge_al<=0;
bridge_bh<=1;
bridge_bl<=((b_up)|bridge_pwm_in);
bridge_ch<=1;
bridge_cl<=0;
end
2:begin
bridge_ah<=0;//(!((!a_up)|bridge_pwm_in));
bridge_al<=0;
bridge_bh<=1;
bridge_bl<=0;
bridge_ch<=1;
bridge_cl<=((c_up)|bridge_pwm_in);
end
3:begin
bridge_ah<=1;
bridge_al<=0;
bridge_bh<=0;//(!((!b_up)|bridge_pwm_in));
bridge_bl<=0;
bridge_ch<=1;
bridge_cl<=((c_up)|bridge_pwm_in);
end
4:begin
bridge_ah<=1;
bridge_al<=((a_up)|bridge_pwm_in);
bridge_bh<=0;//(!((!b_up)|bridge_pwm_in));
bridge_bl<=0;
bridge_ch<=1;
bridge_cl<=0;
end
5:begin
bridge_ah<=1;
bridge_al<=((a_up)|bridge_pwm_in);
bridge_bh<=1;
bridge_bl<=0;
bridge_ch<=0;//(!((!c_up)|bridge_pwm_in));
bridge_cl<=0;
end
6:begin
bridge_ah<=1;
bridge_al<=0;
bridge_bh<=1;
bridge_bl<=((b_up)|bridge_pwm_in);
bridge_ch<=0;//(!((!c_up)|bridge_pwm_in));
bridge_cl<=0;
end
7:begin
bridge_ah<=!bridge_pwm_in;
bridge_al<=0;
bridge_bh<=1;
bridge_bl<=1;
bridge_ch<=1;
bridge_cl<=1;
end
endcase
end
end
endmodule
FPGA做方波电调纯粹是闲的蛋疼,不如8位单片机 闲蛋疼
补字数 梦幻之旅 发表于 2015-6-11 10:24
FPGA做方波电调纯粹是闲的蛋疼,不如8位单片机
8位单片机方波电调根本不用做额,资料那么多,随便抄个好赢或者ZTW电调的PCB然后刷BLheli就OK了,做多久也没那个好用。。。。 这个思路还是蛮有意思的 具有研究意义,不具有实用意义 marK mikeyaosemiac 发表于 2015-6-11 10:57
8位单片机方波电调根本不用做额,资料那么多,随便抄个好赢或者ZTW电调的PCB然后刷BLheli就OK了,做多久 ...
额。。 确实是这样, 不过LZ可以先把开源代码的原理研究清楚了再用FPGA来做,这样至少先达到开源的效果先呀。
好过现在自己从0开始,这样效率也高,
页:
[1]