mikeyaosemiac 发表于 2015-6-10 18:08:11

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

梦幻之旅 发表于 2015-6-11 10:24:07

FPGA做方波电调纯粹是闲的蛋疼,不如8位单片机

y595906642 发表于 2015-6-11 10:35:43

闲蛋疼
补字数

mikeyaosemiac 发表于 2015-6-11 10:57:06

梦幻之旅 发表于 2015-6-11 10:24
FPGA做方波电调纯粹是闲的蛋疼,不如8位单片机

8位单片机方波电调根本不用做额,资料那么多,随便抄个好赢或者ZTW电调的PCB然后刷BLheli就OK了,做多久也没那个好用。。。。

小小苹果 发表于 2015-8-21 17:30:18

这个思路还是蛮有意思的

jamesdeep 发表于 2015-8-25 00:36:29

具有研究意义,不具有实用意义

lcmdw 发表于 2015-8-29 22:58:19

marK                  

zouyf12 发表于 2015-8-31 00:19:38

mikeyaosemiac 发表于 2015-6-11 10:57
8位单片机方波电调根本不用做额,资料那么多,随便抄个好赢或者ZTW电调的PCB然后刷BLheli就OK了,做多久 ...

额。。 确实是这样, 不过LZ可以先把开源代码的原理研究清楚了再用FPGA来做,这样至少先达到开源的效果先呀。
好过现在自己从0开始,这样效率也高,
页: [1]
查看完整版本: fpga做的电调开源原理图和代码求大神协助解决问题。