搜索
bottom↓
回复: 7

fpga做的电调开源原理图和代码求大神协助解决问题。

[复制链接]

出0入0汤圆

发表于 2015-6-10 18:08:11 | 显示全部楼层 |阅读模式
本帖最后由 mikeyaosemiac 于 2015-6-10 18:11 编辑

先上视频http://v.youku.com/v_show/id_XMTI1OTQ2MzU2MA==.html
电路图

现在问题是噪音巨大而且电流也很大,似乎有许多换相是错误的。我把我的代码贴上来希望大神能够帮忙看一眼哪里有错误
整体算法是下桥PWM,PWM低电平同步比较器采样,换相后7.5度开始检测过零,过零后15度执行换相(0-30度都试过,不好使)

下面是自动换向器模块的代码
  1. module auto_commutator_sydelay(ac_clk,ac_en,ac_rst,ac_01a,ac_01b,ac_01c,ac_10a,ac_10b,ac_10c,ac_phase
  2.     );
  3. 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的变化
  4. output[3:0] ac_phase;
  5. reg[3:0] ac_phase;
  6. reg count_flag;
  7. reg[23:0] count;
  8. reg[23:0] demag_count;
  9. wire count_zero;
  10. assign count_zero=(count<11);
  11. parameter[3:0]
  12.         P_0=0,
  13.         P_1=1,
  14.         P_2=2,
  15.         P_3=3,
  16.         P_4=4,
  17.         P_5=5,
  18.         P_6=6,
  19.         P_1d=7,
  20.         P_2d=8,
  21.         P_3d=9,
  22.         P_4d=10,
  23.         P_5d=11,
  24.         P_6d=12;
  25. reg [15:0]state,next_state;       
  26. 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)\\检测到过零事件或者等待换相事件到达
  27.    begin
  28.    next_state=16'b0;
  29.           case(1'b1)
  30.             state[P_0]:begin
  31.                if(ac_en)
  32.                       begin
  33.                                   next_state[P_1]=1'b1;
  34.                                   ac_phase=1;
  35.                                  // count_flag=0;
  36.                                 end
  37.                          else
  38.                            begin
  39.                                   next_state[P_0]=1'b1;
  40.                                   ac_phase=0;
  41.                                   
  42.                                 end
  43.              end
  44.                  state[P_1]:begin
  45.                if((ac_01c==1)&&(count>demag_count))\\当比较器发生跳变且距离上一次换相已经大于7.5电角度时过零事件有效(利用7.5电角度来屏蔽消磁)
  46.                       begin
  47.                                   next_state[P_1d]=1'b1;
  48.                                   demag_count<=(count>>2);
  49.                                   ac_phase=1;
  50.                                 end
  51.                          else
  52.                            begin
  53.                                   next_state[P_1]=1'b1;
  54.                                   ac_phase=1;
  55.                                 end
  56.              end
  57.                   state[P_1d]:begin//过零后等待等待时间到达,执行换相,这里等待的是15电角度(其他值也是不好),很奇怪。
  58.                if(count_zero)
  59.                       begin
  60.                                   next_state[P_2]=1'b1;
  61.                                   ac_phase=2;
  62.                                 end
  63.                          else
  64.                            begin
  65.                                   next_state[P_1d]=1'b1;
  66.                                   ac_phase=1;
  67.                                 end
  68.              end
  69.                  state[P_2]:begin
  70.                if((ac_10b==1)&&(count>demag_count))
  71.                       begin
  72.                                 demag_count<=(count>>2);
  73.                                   next_state[P_2d]=1'b1;
  74.                                   ac_phase=2;
  75.                                 end
  76.                          else
  77.                            begin
  78.                                   next_state[P_2]=1'b1;
  79.                                   ac_phase=2;
  80.                                 end
  81.              end
  82.                   state[P_2d]:begin
  83.                if(count_zero)
  84.                       begin
  85.                                   next_state[P_3]=1'b1;
  86.                                   ac_phase=3;
  87.                                 end
  88.                          else
  89.                            begin
  90.                                   next_state[P_2d]=1'b1;
  91.                                   ac_phase=2;
  92.                                 end
  93.              end
  94.                  state[P_3]:begin
  95.                if((ac_01a==1)&&(count>demag_count))
  96.                       begin
  97.                                 demag_count<=(count>>2);
  98.                                   next_state[P_3d]=1'b1;
  99.                                   ac_phase=3;
  100.                                 end
  101.                          else
  102.                            begin
  103.                                   next_state[P_3]=1'b1;
  104.                                   ac_phase=3;
  105.                                 end
  106.              end
  107.                   state[P_3d]:begin
  108.                if(count_zero)
  109.                       begin
  110.                                   next_state[P_4]=1'b1;
  111.                                   ac_phase=4;
  112.                                 end
  113.                          else
  114.                            begin
  115.                                   next_state[P_3d]=1'b1;
  116.                                   ac_phase=3;
  117.                                 end
  118.              end
  119.                  state[P_4]:begin
  120.                if((ac_10c==1)&&(count>demag_count))
  121.                       begin
  122.                                 demag_count<=(count>>2);
  123.                                   next_state[P_4d]=1'b1;
  124.                                   ac_phase=4;
  125.                                 end
  126.                          else
  127.                            begin
  128.                                   next_state[P_4]=1'b1;
  129.                                   ac_phase=4;
  130.                                 end
  131.              end
  132.                   state[P_4d]:begin
  133.                if(count_zero)
  134.                       begin
  135.                                   next_state[P_5]=1'b1;
  136.                                   ac_phase=5;
  137.                                 end
  138.                          else
  139.                            begin
  140.                                   next_state[P_4d]=1'b1;
  141.                                   ac_phase=4;
  142.                                 end
  143.              end
  144.                   state[P_5]:begin
  145.                if((ac_01b==1)&&(count>demag_count))
  146.                       begin
  147.                                 demag_count<=(count>>2);
  148.                                   next_state[P_5d]=1'b1;
  149.                                   ac_phase=5;
  150.                                 end
  151.                          else
  152.                            begin
  153.                                   next_state[P_5]=1'b1;
  154.                                   ac_phase=5;
  155.                                 end
  156.              end
  157.                    state[P_5d]:begin
  158.                if(count_zero)
  159.                       begin
  160.                                   next_state[P_6]=1'b1;
  161.                                   ac_phase=6;
  162.                                 end
  163.                          else
  164.                            begin
  165.                                   next_state[P_5d]=1'b1;
  166.                                   ac_phase=5;
  167.                                 end
  168.              end
  169.                   state[P_6]:begin
  170.                if((ac_10a==1)&&(count>demag_count))
  171.                       begin
  172.                                 demag_count<=(count>>2);
  173.                                   next_state[P_6d]=1'b1;
  174.                                   ac_phase=6;
  175.                                 end
  176.                          else
  177.                            begin
  178.                                   next_state[P_6]=1'b1;
  179.                                   ac_phase=6;
  180.                                 end
  181.              end
  182.                   state[P_6d]:begin
  183.                if(count_zero)
  184.                       begin
  185.                                   next_state[P_1]=1'b1;
  186.                                   ac_phase=1;
  187.                                 end
  188.                          else
  189.                            begin
  190.                                   next_state[P_6d]=1'b1;
  191.                                   ac_phase=6;
  192.                                 end
  193.              end
  194.                   default:begin
  195.                     next_state[P_0]=1'b1;
  196.                     ac_phase=0;
  197.                   end
  198.           endcase
  199.         end


  200. always @(negedge ac_rst or posedge ac_clk)
  201.   begin
  202. if (!ac_rst)
  203. begin
  204. state <= (1'b1 << P_0) ;
  205. count<=0;
  206. end
  207. else
  208.     begin
  209.        state <=(next_state) ;
  210.        if((state[P_1]==1)||(state[P_2]==1)||(state[P_3]==1)||(state[P_4]==1)||(state[P_5]==1)||(state[P_6]==1))//计算一个从换相到下一次过零的时间用于过零后到下一次换相的延时
  211.                    begin
  212.                            count<=count+1;
  213.                         end
  214.                   else if((state[P_1d]==1)||(state[P_2d]==1)||(state[P_3d]==1)||(state[P_4d]==1)||(state[P_5d]==1)||(state[P_6d]==1)) //计算一个从换相到下一次过零的时间用于过零后到下一次换相的延时
  215.                    begin
  216.                            count<=count-2;
  217.                         end
  218.          end
  219.   end


  220. endmodule
复制代码

过零探测模块

  1. module zero_detector(zd_clk,zd_rst,zd_in,zd_sync,zd_01out,zd_10out
  2.     );
  3. input zd_clk,zd_rst,zd_in,zd_sync;
  4. output zd_01out;
  5. wire zd_01out;
  6. output zd_10out;
  7. wire zd_10out;
  8. reg[1:0] zd_state_now;
  9. reg c_state;
  10. reg[3:0] filter_buf;
  11. assign zd_10out=zd_state_now[1]&(!zd_state_now[0]);
  12. assign zd_01out=zd_state_now[0]&(!zd_state_now[1]);//zd_state_now[1]^zd_state_now[0];
  13. always @(posedge zd_clk,negedge zd_rst)
  14.   begin
  15.   zd_state_now<={zd_state_now[0],c_state};
  16.         if(!zd_rst)
  17.      begin
  18.      zd_state_now<=0;
  19.           end
  20.          else
  21.            begin
  22.                 if(filter_buf[1:0]==0)
  23.                   begin
  24.                c_state<=0;
  25.              end
  26.                 else if(filter_buf[1:0]==3)//检测到两个0或两个1的读数则认为此时读数为0或1
  27.         begin
  28.           c_state<=1;
  29.                   end                  
  30.                 end
  31.    end
  32. always @(posedge zd_sync)
  33.   begin
  34.   filter_buf<={filter_buf[2:0],zd_in};//同步的采样。每次在PWM为低电平即将翻转成高电平之前会到来zd_sync
  35.   end
  36.   
  37. endmodule
复制代码

驱动桥模块,下桥PWM
  1. 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
  2.     );
  3. input bridge_rst,bridge_clk,bridge_pwm_in,a_up,b_up,c_up;
  4. input[3:0] bridge_phase;
  5. output bridge_ah,bridge_al,bridge_bh,bridge_bl,bridge_ch,bridge_cl;
  6. reg bridge_ah,bridge_al,bridge_bh,bridge_bl,bridge_ch,bridge_cl;

  7. always @ (posedge bridge_clk or negedge bridge_rst)
  8. begin
  9.   if(!bridge_rst)
  10.     begin
  11.                 bridge_ah<=1;
  12.                 bridge_al<=0;
  13.                 bridge_bh<=1;
  14.                 bridge_bl<=0;
  15.                 bridge_ch<=1;
  16.                 bridge_cl<=0;
  17.     end
  18.   else
  19.     begin
  20.            case(bridge_phase)
  21.            0:begin
  22.                bridge_ah<=1;
  23.                     bridge_al<=0;
  24.                     bridge_bh<=1;
  25.                     bridge_bl<=0;
  26.                     bridge_ch<=1;
  27.                     bridge_cl<=0;
  28.                   end
  29.                 1:begin
  30.                bridge_ah<=0;//(!((!a_up)|bridge_pwm_in));
  31.                     bridge_al<=0;
  32.                     bridge_bh<=1;
  33.                     bridge_bl<=((b_up)|bridge_pwm_in);
  34.                     bridge_ch<=1;
  35.                     bridge_cl<=0;
  36.                   end
  37.                                   2:begin
  38.                bridge_ah<=0;//(!((!a_up)|bridge_pwm_in));
  39.                     bridge_al<=0;
  40.                     bridge_bh<=1;
  41.                     bridge_bl<=0;
  42.                     bridge_ch<=1;
  43.                     bridge_cl<=((c_up)|bridge_pwm_in);
  44.                   end
  45.                                   3:begin
  46.                bridge_ah<=1;
  47.                     bridge_al<=0;
  48.                     bridge_bh<=0;//(!((!b_up)|bridge_pwm_in));
  49.                     bridge_bl<=0;
  50.                     bridge_ch<=1;
  51.                     bridge_cl<=((c_up)|bridge_pwm_in);
  52.                   end
  53.                                   4:begin
  54.                bridge_ah<=1;
  55.                     bridge_al<=((a_up)|bridge_pwm_in);
  56.                     bridge_bh<=0;//(!((!b_up)|bridge_pwm_in));
  57.                     bridge_bl<=0;
  58.                     bridge_ch<=1;
  59.                     bridge_cl<=0;
  60.                   end
  61.                                   5:begin
  62.                bridge_ah<=1;
  63.                     bridge_al<=((a_up)|bridge_pwm_in);
  64.                     bridge_bh<=1;
  65.                     bridge_bl<=0;
  66.                     bridge_ch<=0;//(!((!c_up)|bridge_pwm_in));
  67.                     bridge_cl<=0;
  68.                   end
  69.                                   6:begin
  70.                bridge_ah<=1;
  71.                     bridge_al<=0;
  72.                     bridge_bh<=1;
  73.                     bridge_bl<=((b_up)|bridge_pwm_in);
  74.                     bridge_ch<=0;//(!((!c_up)|bridge_pwm_in));
  75.                     bridge_cl<=0;
  76.                   end
  77.                   7:begin
  78.                bridge_ah<=!bridge_pwm_in;
  79.                     bridge_al<=0;
  80.                     bridge_bh<=1;
  81.                     bridge_bl<=1;
  82.                     bridge_ch<=1;
  83.                     bridge_cl<=1;
  84.                   end
  85.       endcase
  86.          end
  87. end
  88. endmodule
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

阿莫论坛才是最爱国的,关心国家的经济、社会的发展、担心国家被别国牵连卷入战争、知道珍惜来之不易的和平发展,知道师夷之长,关注世界的先进文化与技术,也探讨中国文化的博大精深,也懂得警惕民粹主义的祸国殃民等等等等,无不是爱国忧民的表现。(坛友:tianxian)

出0入0汤圆

发表于 2015-6-11 10:24:07 | 显示全部楼层
FPGA做方波电调纯粹是闲的蛋疼,不如8位单片机

出0入0汤圆

发表于 2015-6-11 10:35:43 | 显示全部楼层
闲蛋疼
补字数

出0入0汤圆

 楼主| 发表于 2015-6-11 10:57:06 | 显示全部楼层
梦幻之旅 发表于 2015-6-11 10:24
FPGA做方波电调纯粹是闲的蛋疼,不如8位单片机

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

出0入0汤圆

发表于 2015-8-21 17:30:18 | 显示全部楼层
这个思路还是蛮有意思的

出0入0汤圆

发表于 2015-8-25 00:36:29 | 显示全部楼层
具有研究意义,不具有实用意义

出0入0汤圆

发表于 2015-8-29 22:58:19 来自手机 | 显示全部楼层
marK                  

出0入0汤圆

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

额。。 确实是这样, 不过LZ可以先把开源代码的原理研究清楚了再用FPGA来做,这样至少先达到开源的效果先呀。
好过现在自己从0开始,这样效率也高,  
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-17 08:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表