飞道的博客

【FPGA+PWM】基于FPGA的PWM控制器实现

533人阅读  评论(0)

1.软件版本

matlab2013b,ISE14.7

2.系统原理

我们把里面的各个模块进行仿真:

模块一的设计:

先设计第一级的三个模块:

 

  

这里,这三个模块都是一样的,其基本的公式为:

里面的公式是,首先是WT输出cos和sin对应公式中的1和2

然后abc三相输出为3,4,5角。里面的公式为:

simulink仿真结果如下所示:

我们设计的FPGA的仿真结果如下所示:

 

这里,我们主要对多个不同截止频率的低通滤波器进行设计。

这里,主要有截止频率为10,30,100,和8000四种不同的截止频率的低通滤波器

在simulink中仿真结果如下所示:

我们设计的fpga仿真结果如下所示:

dq转ABC的模块:

u[1]*u[4] + u[2]*u[3]

.5*(-u(1)+1.732*u(2))*u(4)  +  .5*(-u(2)-1.732*u(1))*u(3)

我们再FPGA中进行设计。得到的仿真结果如下所示:

然后进行整个控制器的设计:

        我们根据控制器的内部结构进行编程:

整个模块的整体构架如下所示:

整个程序分为两个顶层文件,上面这个是我在FPGA内部模拟的测试调用文件,你不需要看这个,

下面这个是根据你的simulink设计的顶层模块,其基本管脚如下所示:

注意,输入的三相电流和电压部分,在FPGA中设计必须分开写,所以输入脚看上去很多,实际就是几个三相变量,另外输入部分的i_clk和i_rst是fpga必须用的脚,一个是时钟变量,一个是复位,正常工作的时候复位为0,如果复位为1,那么系统初始化为0.

再看输出,也是simulink对应的,其中几个test变量,是我在设计过程中保留的测试端口,实际中不使用。

      然后我们看整个控制器的测试,将设置为顶层文件,然后进行仿真,仿真结果如下所示:

其中六个控制PWM波形如下所示:

3.部分源码


  
  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 02:07:36 11/24/2013
  7. // Design Name:
  8. // Module Name: Controller_tops
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module Controller_tops(
  22. i_clk,
  23. i_rst,
  24. i_ifa,i_ifb,i_ifc,
  25. i_iia,i_iib,i_iic,
  26. i_vdc,
  27. i_vsa,i_vsb,i_vsc,
  28. i_vsa1,i_vsb1,i_vsc1,
  29. o_PWM1,o_PWM2,o_PWM3,o_PWM4,o_PWM5,o_PWM6,
  30. o_power,
  31. o_wt,
  32. o_connect,
  33. o_af_on,
  34. o_test_port1,
  35. o_test_port2,
  36. o_test_port3,
  37. o_test_port4
  38. );
  39. parameter VDC = 10;
  40. input i_clk;
  41. input i_rst;
  42. input signed[ 11: 0]i_ifa,i_ifb,i_ifc;
  43. input signed[ 11: 0]i_iia,i_iib,i_iic;
  44. input signed[ 11: 0]i_vdc;
  45. input signed[ 11: 0]i_vsa,i_vsb,i_vsc;
  46. input signed[ 11: 0]i_vsa1,i_vsb1,i_vsc1;
  47. output signed[ 1: 0]o_PWM1,o_PWM2,o_PWM3,o_PWM4,o_PWM5,o_PWM6;
  48. output signed[ 11: 0]o_power;
  49. output [ 10: 0]o_wt;
  50. output o_connect;
  51. output o_af_on;
  52. output signed[ 11: 0]o_test_port1;
  53. output signed[ 11: 0]o_test_port2;
  54. output signed[ 11: 0]o_test_port3;
  55. output signed[ 11: 0]o_test_port4;
  56. //PLL
  57. reg [ 10: 0]o_wt;
  58. always @(posedge i_clk or posedge i_rst)
  59. begin
  60. if(i_rst)
  61. begin
  62. o_wt <= 11'd0;
  63. end
  64. else begin
  65. o_wt <= o_wt + 11'd20;
  66. end
  67. end
  68. //===========================================================================
  69. //abc>dq i_filt stationary
  70. //===========================================================================
  71. wire signed[ 11: 0]d_ifa;
  72. wire signed[ 11: 0]q_ifa;
  73. abc_dq abc_dq_ifabc(
  74. .i_clk (i_clk),
  75. .i_rst (i_rst),
  76. .i_A (i_ifa),
  77. .i_B (i_ifb),
  78. .i_C (i_ifc),
  79. .i_theta (11'd0),
  80. .o_d (d_ifa),
  81. .o_q (q_ifa),
  82. .test_cos(),
  83. .test_sin()
  84. );
  85. wire signed[ 11: 0]d_ifa_filter;
  86. wire signed[ 11: 0]q_ifa_filter;
  87. lowpass_8000Hz_tops lowpass_8000Hz_uifabc1(
  88. .i_clk (i_clk),
  89. .i_rst (i_rst),
  90. .i_data (d_ifa),
  91. .o_data (d_ifa_filter)
  92. );
  93. lowpass_8000Hz_tops lowpass_8000Hz_uifabc2(
  94. .i_clk (i_clk),
  95. .i_rst (i_rst),
  96. .i_data (q_ifa),
  97. .o_data (q_ifa_filter)
  98. );
  99. //===========================================================================
  100. //abc>dq i_load rotating
  101. //===========================================================================
  102. wire signed[ 11: 0]d_iload;
  103. wire signed[ 11: 0]q_iload;
  104. abc_dq abc_dq_iload(
  105. .i_clk (i_clk),
  106. .i_rst (i_rst),
  107. .i_A (i_iia),
  108. .i_B (i_iib),
  109. .i_C (i_iic),
  110. .i_theta (o_wt),
  111. .o_d (d_iload),
  112. .o_q (q_iload),
  113. .test_cos(),
  114. .test_sin()
  115. );
  116. wire signed[ 11: 0]q_iload_filter;
  117. wire signed[ 11: 0]q_iload_filter2;
  118. lowpass_10Hz_tops lowpass_10Hz_tops_iload(
  119. .i_clk (i_clk),
  120. .i_rst (i_rst),
  121. .i_data(q_iload),
  122. .o_data(q_iload_filter)
  123. );
  124. assign q_iload_filter2 = q_iload-q_iload_filter;
  125. assign o_power = q_iload_filter;
  126. wire signed[ 11: 0]add1;
  127. wire signed[ 11: 0]add2;
  128. wire signed[ 11: 0]add3;
  129. wire signed[ 11: 0]add4;
  130. wire signed[ 11: 0]add5;
  131. assign add1 = d_iload;
  132. assign add3 = q_iload_filter2;
  133. assign add4 = (q_iload_filter>= 28)? 4: 0;
  134. //VDC
  135. wire signed[ 11: 0]vdc_filter;
  136. wire signed[ 11: 0]vdc_filterx;
  137. lowpass_30Hz_tops lowpass_30Hz_tops_vdc(
  138. .i_clk (i_clk),
  139. .i_rst (i_rst),
  140. .i_data(i_vdc),
  141. .o_data(vdc_filter)
  142. );
  143. assign vdc_filterx = VDC-vdc_filter;
  144. wire flag; //<-0.1
  145. assign flag = (q_iload_filter < -128)? 1: 0;
  146. wire signed[ 11: 0]PIDX;
  147. wire signed[ 11: 0]PID;
  148. wire signed[ 11: 0]PIDO;
  149. reg signed[ 11: 0]PID1;
  150. reg signed[ 11: 0]PID21;
  151. reg signed[ 11: 0]PID22;
  152. always @(posedge i_clk or posedge i_rst)
  153. begin
  154. if(i_rst)
  155. begin
  156. PID1 <= 12'd0;
  157. PID21 <= 12'd0;
  158. PID22 <= 12'd0;
  159. end
  160. else begin
  161. PID1 <= vdc_filterx;
  162. PID21 <= PID21+vdc_filterx;
  163. PID22 <= PID21;
  164. end
  165. end
  166. assign PIDX = PID21;
  167. assign PID = PID1/ 64 + PIDX/ 128;
  168. assign PIDO = (flag > 0)? vdc_filterx: 0;
  169. wire signed[ 11: 0]d_vr;
  170. wire signed[ 11: 0]q_vr;
  171. wire signed[ 23: 0]add2s;
  172. wire signed[ 23: 0]add5s;
  173. assign add2s = PIDO*d_vr;
  174. assign add5s = PIDO*q_vr;
  175. assign add2 = add2s[ 23: 12];
  176. assign add5 = add5s[ 23: 12];
  177. wire signed[ 11: 0]vds;
  178. wire signed[ 11: 0]vqs;
  179. assign vds = add1 + add2;
  180. assign vqs = add3 + add4 + add5;
  181. wire signed[ 11: 0]Axx;
  182. wire signed[ 11: 0]Bxx;
  183. wire signed[ 11: 0]Cxx;
  184. dq_abc dq_abc_u5(
  185. .i_clk (i_clk),
  186. .i_rst (i_rst),
  187. .i_wt (o_wt),
  188. .i_vd (vds),
  189. .i_vq (vqs),
  190. .o_At (Axx),
  191. .o_Bt (Bxx),
  192. .o_Ct (Cxx)
  193. );
  194. wire signed[ 11: 0]dvrrr;
  195. wire signed[ 11: 0]qvrrr;
  196. abc_dq abc_dq_vr(
  197. .i_clk (i_clk),
  198. .i_rst (i_rst),
  199. .i_A (Axx),
  200. .i_B (Bxx),
  201. .i_C (Cxx),
  202. .i_theta (0),
  203. .o_d (dvrrr),
  204. .o_q (qvrrr),
  205. .test_cos(),
  206. .test_sin()
  207. );
  208. //===========================================================================
  209. //abc >dq Vsource rotating
  210. //===========================================================================
  211. abc_dq abc_dq_vr22(
  212. .i_clk (i_clk),
  213. .i_rst (i_rst),
  214. .i_A (i_vsa),
  215. .i_B (i_vsb),
  216. .i_C (i_vsc),
  217. .i_theta (o_wt),
  218. .o_d (d_vr),
  219. .o_q (q_vr),
  220. .test_cos(),
  221. .test_sin()
  222. );
  223. wire signed[ 11: 0]d_vr_filter;
  224. wire signed[ 11: 0]q_vr_filter;
  225. lowpass_100Hz_tops lowpass_100Hz_vr1(
  226. .i_clk (i_clk),
  227. .i_rst (i_rst),
  228. .i_data (d_vr),
  229. .o_data (d_vr_filter)
  230. );
  231. lowpass_100Hz_tops lowpass_100Hz_vr2(
  232. .i_clk (i_clk),
  233. .i_rst (i_rst),
  234. .i_data (q_vr),
  235. .o_data (q_vr_filter)
  236. );
  237. //===========================================================================
  238. //abc >dq Vsource1 rotating
  239. //===========================================================================
  240. wire signed[ 11: 0]d_vr1;
  241. wire signed[ 11: 0]q_vr1;
  242. abc_dq abc_dq_vr1(
  243. .i_clk (i_clk),
  244. .i_rst (i_rst),
  245. .i_A (i_vsa1),
  246. .i_B (i_vsb1),
  247. .i_C (i_vsc1),
  248. .i_theta (o_wt),
  249. .o_d (d_vr1),
  250. .o_q (q_vr1),
  251. .test_cos(),
  252. .test_sin()
  253. );
  254. wire signed[ 11: 0]d_vrx;
  255. wire signed[ 11: 0]q_vrx;
  256. assign d_vrx = d_vr - d_vr1;
  257. assign q_vrx = q_vr - q_vr1;
  258. wire signed[ 11: 0]d_vrx_filter;
  259. wire signed[ 11: 0]q_vrx_filter;
  260. lowpass_100Hz_tops lowpass_100Hz_vr11(
  261. .i_clk (i_clk),
  262. .i_rst (i_rst),
  263. .i_data (d_vrx),
  264. .o_data (d_vrx_filter)
  265. );
  266. lowpass_100Hz_tops lowpass_100Hz_vr12(
  267. .i_clk (i_clk),
  268. .i_rst (i_rst),
  269. .i_data (q_vrx),
  270. .o_data (q_vrx_filter)
  271. );
  272. wire signed[ 11: 0]d_vrx_filter2;
  273. wire signed[ 11: 0]q_vrx_filter2;
  274. assign d_vrx_filter2 = {d_vrx_filter[ 11],d_vrx_filter[ 11],d_vrx_filter[ 11],d_vrx_filter[ 11: 3]};
  275. assign q_vrx_filter2 = {q_vrx_filter[ 11],q_vrx_filter[ 11],q_vrx_filter[ 11],q_vrx_filter[ 11],q_vrx_filter[ 11: 4]};
  276. wire signed[ 11: 0]o_Avrx;
  277. wire signed[ 11: 0]o_Bvrx;
  278. wire signed[ 11: 0]o_Cvrx;
  279. dq_abc dq_abc_u1(
  280. .i_clk (i_clk),
  281. .i_rst (i_rst),
  282. .i_wt (o_wt),
  283. .i_vd (d_vrx_filter2),
  284. .i_vq (q_vrx_filter2),
  285. .o_At (o_Avrx),
  286. .o_Bt (o_Bvrx),
  287. .o_Ct (o_Cvrx)
  288. );
  289. //===========================================================================
  290. //xxxxxxxxxxxxxxxxxxxxx
  291. //===========================================================================
  292. wire signed[ 11: 0]d_vrx1;
  293. wire signed[ 11: 0]q_vrx1;
  294. wire signed[ 11: 0]d_vrx2;
  295. wire signed[ 11: 0]q_vrx2;
  296. wire signed[ 11: 0]d_vrxx2;
  297. wire signed[ 11: 0]q_vrxx2;
  298. abc_dq abc_dq_dqvx1(
  299. .i_clk (i_clk),
  300. .i_rst (i_rst),
  301. .i_A (i_vsa),
  302. .i_B (i_vsb),
  303. .i_C (i_vsc),
  304. .i_theta (o_wt),
  305. .o_d (d_vrx1),
  306. .o_q (q_vrx1),
  307. .test_cos(),
  308. .test_sin()
  309. );
  310. abc_dq abc_dq_dqvx2(
  311. .i_clk (i_clk),
  312. .i_rst (i_rst),
  313. .i_A (o_Avrx),
  314. .i_B (o_Bvrx),
  315. .i_C (o_Cvrx),
  316. .i_theta (o_wt),
  317. .o_d (d_vrx2),
  318. .o_q (q_vrx2),
  319. .test_cos(),
  320. .test_sin()
  321. );
  322. assign d_vrxx2 = d_vrx1 - d_vrx2;
  323. assign q_vrxx2 = q_vrx1 - q_vrx2;
  324. wire signed[ 11: 0]X1;
  325. wire signed[ 11: 0]X2;
  326. wire signed[ 11: 0]X3;
  327. wire signed[ 11: 0]X4;
  328. wire signed[ 11: 0]X5;
  329. wire signed[ 11: 0]X6;
  330. assign X1 = dvrrr-d_ifa_filter;
  331. assign X2 = qvrrr-q_ifa_filter;
  332. assign X3 = {i_vdc[ 11],i_vdc[ 11: 1]};
  333. assign X4 = d_vrxx2;
  334. assign X5 = q_vrxx2;
  335. assign X6 = o_wt;
  336. wire signed[ 15: 0]r1r;
  337. wire signed[ 15: 0]r2r;
  338. assign r1r = 5*X1 + X4;
  339. assign r2r = 5*X2 + X5;
  340. wire signed[ 23: 0]r1r2;
  341. wire signed[ 23: 0]r2r2;
  342. assign r1r2 = -887*r1r;
  343. assign r2r2 = 887*r2r;
  344. wire signed[ 11: 0]r1r3;
  345. wire signed[ 11: 0]r2r3;
  346. assign r1r3 = r1r2[ 23: 12];
  347. assign r2r3 = r2r2[ 23: 12];
  348. //generator PWM
  349. wire signed[ 11: 0]SVGA;
  350. wire signed[ 11: 0]SVGB;
  351. wire signed[ 11: 0]SVGC;
  352. SVG SVG_u(
  353. .i_clk(i_clk),
  354. .i_rst(i_rst),
  355. .i_m(r1r3),
  356. .i_n(r2r3),
  357. .o_A(SVGA),
  358. .o_B(SVGB),
  359. .o_C(SVGC)
  360. );
  361. reg signed[ 1: 0] seq;
  362. reg [ 7: 0]cnt00;
  363. always @(posedge i_clk or posedge i_rst)
  364. begin
  365. if(i_rst)
  366. begin
  367. cnt00 <= 8'd0;
  368. end
  369. else begin
  370. cnt00 <= cnt00 + 1;
  371. if(cnt00[ 7: 6] == 2'b00)
  372. seq <= 2'b00;
  373. if(cnt00[ 7: 6] == 2'b01)
  374. seq <= 2'b01;
  375. if(cnt00[ 7: 6] == 2'b10)
  376. seq <= 2'b00;
  377. if(cnt00[ 7: 6] == 2'b11)
  378. seq <= 2'b11;
  379. end
  380. end
  381. assign o_PWM1 = (SVGA[ 11: 10] > seq)? 2'b01 : 2'b11;
  382. assign o_PWM2 = ~o_PWM1;
  383. assign o_PWM3 = (SVGB[ 11: 10] > seq)? 2'b01 : 2'b11;
  384. assign o_PWM4 = ~o_PWM3;
  385. assign o_PWM5 = (SVGC[ 11: 10] > seq)? 2'b01 : 2'b11;
  386. assign o_PWM6 = ~o_PWM5;
  387. assign o_test_port1 = r1r[ 15: 4];
  388. assign o_test_port2 = r2r[ 15: 4];
  389. assign o_test_port3 = r1r3;
  390. assign o_test_port4 = r2r3;
  391. wire flag1;
  392. wire flag2;
  393. wire flag0;
  394. assign flag1=(o_wt >= 12'd1900)? 1: 0;
  395. assign flag2=(o_wt <= 12'd2000)? 1: 0;
  396. assign flag0= flag1 & flag2;
  397. reg o_connect;
  398. reg o_af_on;
  399. reg[ 7: 0]cnt1;
  400. reg[ 7: 0]cnt2;
  401. reg flagd;
  402. always @(posedge i_clk or posedge i_rst)
  403. begin
  404. if(i_rst)
  405. begin
  406. flagd<= 1'b0;
  407. end
  408. else begin
  409. flagd <= flag0;
  410. end
  411. end
  412. always @(posedge i_clk or posedge i_rst)
  413. begin
  414. if(i_rst)
  415. begin
  416. cnt1 <= 8'd0;
  417. o_connect <= 1'b0;
  418. end
  419. else begin
  420. if(flagd == 1'b0 & flag0 == 1'b1)
  421. begin
  422. if(cnt1 == 10)
  423. cnt1 <= 1;
  424. else
  425. cnt1 <= cnt1 + 1;
  426. end
  427. else begin
  428. cnt1 <= cnt1;
  429. end
  430. if(cnt1 == 10)
  431. o_connect <= 1'b1;
  432. else
  433. o_connect <= 1'b0;
  434. end
  435. end
  436. always @(posedge i_clk or posedge i_rst)
  437. begin
  438. if(i_rst)
  439. begin
  440. cnt2 <= 8'd0;
  441. o_af_on <= 1'b0;
  442. end
  443. else begin
  444. if(flagd == 1'b0 & flag0 == 1'b1)
  445. begin
  446. if(cnt2 == 5)
  447. cnt2 <= 1;
  448. else
  449. cnt2 <= cnt2 + 1;
  450. end
  451. else begin
  452. cnt2 <= cnt2;
  453. end
  454. if(cnt2 == 5)
  455. o_af_on <= 1'b1;
  456. else
  457. o_af_on <= 1'b0;
  458. end
  459. end
  460. //output
  461. //output signed[1:0]o_PWM1,o_PWM2,o_PWM3,o_PWM4,o_PWM5,o_PWM6;
  462. //output signed[11:0]o_power;
  463. //output signed[10:0]o_wt;
  464. //output signed[11:0]o_connect;
  465. //output signed[11:0]o_af_on;
  466. endmodule

A08-24


转载:https://blog.csdn.net/ccsss22/article/details/125688785
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场