当前位置:   article > 正文

基于FPGA的正弦PWM产生系统verilog实现_怎么用正弦波产生pwm

怎么用正弦波产生pwm

目录

一、理论基础

二、案例背景

三、部分FPGA仿真

四、仿真结论分析

五、参考文献


一、理论基础

根据如下公式,首先建立simulink仿真模型:

        这里,主要需要设计cos模块。三个余弦输出其分别有120度的相位差。其中,各个参数值为:U1:50;U2:150;U3:时钟t;U4:1;

 

二、案例背景

        pwm也即脉冲宽度调制,通过pwm,可以对脉冲带宽加以调节。对于pwm技术,自动化、电子方面的朋友更为熟悉。为增进大家对pwm的了解程度,本文将对pwm控制以及spwm波的生成予以介绍。如果你对pwm具有兴趣,不妨继续往下阅读哦。

  PWM(PulseWidthModulaTIon)控制就是对脉冲的宽度进行调制的技术。即通过对一系列脉冲的宽度进行调制,来等效地获得所需要的波形。PWM控制技术在逆变电路中的应用最为广泛,对逆变电路的影响也最为深刻,PWM控制技术在逆变电路中的应用也最具代表性。

  面积等效原理是PWM控制技术的重要理论基础,即在采样控制中,冲量相等而形状不同的窄脉冲加在具有惯性的同一环节上时,其效果基本相同。其中,冲量指的是窄脉冲的面积;效果基本相同是指环节的输出响应波形基本相同。

         脉冲幅值相等而脉冲宽度按正弦规律变化而正弦波等效的PWM波称为SPWM(sinusoidalPWM)波形。

三、部分FPGA程序

顶层程序如下:

  1. `timescale 1ns / 1ps
  2. module main_tops(
  3. i_clk,
  4. i_rst,
  5. o_Va,
  6. o_Vb,
  7. o_Vc,
  8. o_Mi,
  9. o_Triger,
  10. o_secteur,
  11. o_theta,
  12. o_Mi2,
  13. o_S1,
  14. o_S2,
  15. o_S3
  16. );
  17. input i_clk;
  18. input i_rst;
  19. output signed[23:0]o_Va;
  20. output signed[23:0]o_Vb;
  21. output signed[23:0]o_Vc;
  22. output signed[23:0]o_Mi;
  23. output o_Triger;
  24. output signed[3:0] o_secteur;
  25. output signed[15:0]o_theta;
  26. output signed[15:0]o_Mi2;
  27. output signed[1:0] o_S1;
  28. output signed[1:0] o_S2;
  29. output signed[1:0] o_S3;
  30. Generating_Extension_switching_signals U1(
  31. .i_clk (i_clk),
  32. .i_rst (i_rst),
  33. .o_Va (o_Va),
  34. .o_Vb (o_Vb),
  35. .o_Vc (o_Vc),
  36. .o_Mi (o_Mi)
  37. );
  38. Calcule_secteur_Vref_pLus_Theta U2(
  39. .i_clk (i_clk),
  40. .i_rst (i_rst),
  41. .i_Va (o_Va[23:8]),
  42. .i_Vb (o_Vb[23:8]),
  43. .i_Vc (o_Vc[23:8]),
  44. .i_Mi (o_Mi[23:8]),
  45. .o_Triger (o_Triger),
  46. .o_secteur(o_secteur),
  47. .o_theta (o_theta),
  48. .o_Mi (o_Mi2),
  49. .o_Y (),
  50. .o_X ()
  51. );
  52. TaTbTc TaTbTc_u(
  53. .i_clk (i_clk),
  54. .i_rst (i_rst),
  55. .i_triger (o_Triger),
  56. .i_secteur (o_secteur),
  57. .i_theta (o_theta),
  58. .i_Mi (o_Mi2),
  59. .o_S1 (o_S1),
  60. .o_S2 (o_S2),
  61. .o_S3 (o_S3)
  62. );
  63. endmodule

Ta ,Tb,Tc模块如下:

  1. `timescale 1ns / 1ps
  2. module TaTbTc(
  3. i_clk,
  4. i_rst,
  5. i_triger,
  6. i_secteur,
  7. i_theta,
  8. i_Mi,
  9. o_S1,
  10. o_S2,
  11. o_S3
  12. );
  13. input i_clk;
  14. input i_rst;
  15. input i_triger;
  16. input [3:0] i_secteur;
  17. input signed[15:0] i_theta;
  18. input signed[15:0] i_Mi;
  19. output signed[1:0] o_S1;
  20. output signed[1:0] o_S2;
  21. output signed[1:0] o_S3;
  22. wire signed[1:0] S11;
  23. wire signed[1:0] S12;
  24. wire signed[1:0] S13;
  25. TaTbTc1 TaTbTc1_u(
  26. .i_clk (i_clk),
  27. .i_rst (i_rst),
  28. .i_triger (i_triger),
  29. .i_secteur (i_secteur),
  30. .i_theta (i_theta),
  31. .i_Mi (i_Mi),
  32. .o_cos1 (),
  33. .o_cos2 (),
  34. .o_cos1_samples (),
  35. .o_cos2_samples (),
  36. .o_Ta (),
  37. .o_Tb (),
  38. .o_Tc (),
  39. .o_deadtime1 (S11),
  40. .o_deadtime2 (S12),
  41. .o_deadtime3 (S13),
  42. //test
  43. .A1 (),
  44. .A2 (),
  45. .B1 (),
  46. .B2 (),
  47. .C1 (),
  48. .C2 (),
  49. .CNTs (),
  50. .flag11 (),
  51. .flag12 (),
  52. .flag21 (),
  53. .flag22 (),
  54. .flag31 (),
  55. .flag32 ()
  56. );
  57. wire signed[1:0] S21;
  58. wire signed[1:0] S22;
  59. wire signed[1:0] S23;
  60. TaTbTc2 TaTbTc2_u(
  61. .i_clk (i_clk),
  62. .i_rst (i_rst),
  63. .i_triger (i_triger),
  64. .i_secteur (i_secteur),
  65. .i_theta (i_theta),
  66. .i_Mi (i_Mi),
  67. .o_cos1 (),
  68. .o_cos2 (),
  69. .o_cos1_samples (),
  70. .o_cos2_samples (),
  71. .o_Ta (),
  72. .o_Tb (),
  73. .o_Tc (),
  74. .o_deadtime1 (S21),
  75. .o_deadtime2 (S22),
  76. .o_deadtime3 (S23),
  77. //test
  78. .A1 (),
  79. .A2 (),
  80. .B1 (),
  81. .B2 (),
  82. .C1 (),
  83. .C2 (),
  84. .CNTs (),
  85. .flag11 (),
  86. .flag12 (),
  87. .flag21 (),
  88. .flag22 (),
  89. .flag31 (),
  90. .flag32 ()
  91. );
  92. wire signed[1:0] S31;
  93. wire signed[1:0] S32;
  94. wire signed[1:0] S33;
  95. TaTbTc3 TaTbTc3_u(
  96. .i_clk (i_clk),
  97. .i_rst (i_rst),
  98. .i_triger (i_triger),
  99. .i_secteur (i_secteur),
  100. .i_theta (i_theta),
  101. .i_Mi (i_Mi),
  102. .o_cos1 (),
  103. .o_cos2 (),
  104. .o_cos1_samples (),
  105. .o_cos2_samples (),
  106. .o_Ta (),
  107. .o_Tb (),
  108. .o_Tc (),
  109. .o_deadtime1 (S31),
  110. .o_deadtime2 (S32),
  111. .o_deadtime3 (S33),
  112. //test
  113. .A1 (),
  114. .A2 (),
  115. .B1 (),
  116. .B2 (),
  117. .C1 (),
  118. .C2 (),
  119. .CNTs (),
  120. .flag11 (),
  121. .flag12 (),
  122. .flag21 (),
  123. .flag22 (),
  124. .flag31 (),
  125. .flag32 ()
  126. );
  127. wire signed[1:0] S41;
  128. wire signed[1:0] S42;
  129. wire signed[1:0] S43;
  130. TaTbTc4 TaTbTc4_u(
  131. .i_clk (i_clk),
  132. .i_rst (i_rst),
  133. .i_triger (i_triger),
  134. .i_secteur (i_secteur),
  135. .i_theta (i_theta),
  136. .i_Mi (i_Mi),
  137. .o_cos1 (),
  138. .o_cos2 (),
  139. .o_cos1_samples (),
  140. .o_cos2_samples (),
  141. .o_Ta (),
  142. .o_Tb (),
  143. .o_Tc (),
  144. .o_deadtime1 (S41),
  145. .o_deadtime2 (S42),
  146. .o_deadtime3 (S43),
  147. //test
  148. .A1 (),
  149. .A2 (),
  150. .B1 (),
  151. .B2 (),
  152. .C1 (),
  153. .C2 (),
  154. .CNTs (),
  155. .flag11 (),
  156. .flag12 (),
  157. .flag21 (),
  158. .flag22 (),
  159. .flag31 (),
  160. .flag32 ()
  161. );
  162. wire signed[1:0] S51;
  163. wire signed[1:0] S52;
  164. wire signed[1:0] S53;
  165. TaTbTc5 TaTbTc5_u(
  166. .i_clk (i_clk),
  167. .i_rst (i_rst),
  168. .i_triger (i_triger),
  169. .i_secteur (i_secteur),
  170. .i_theta (i_theta),
  171. .i_Mi (i_Mi),
  172. .o_cos1 (),
  173. .o_cos2 (),
  174. .o_cos1_samples (),
  175. .o_cos2_samples (),
  176. .o_Ta (),
  177. .o_Tb (),
  178. .o_Tc (),
  179. .o_deadtime1 (S51),
  180. .o_deadtime2 (S52),
  181. .o_deadtime3 (S53),
  182. //test
  183. .A1 (),
  184. .A2 (),
  185. .B1 (),
  186. .B2 (),
  187. .C1 (),
  188. .C2 (),
  189. .CNTs (),
  190. .flag11 (),
  191. .flag12 (),
  192. .flag21 (),
  193. .flag22 (),
  194. .flag31 (),
  195. .flag32 ()
  196. );
  197. wire signed[1:0] S61;
  198. wire signed[1:0] S62;
  199. wire signed[1:0] S63;
  200. TaTbTc6 TaTbTc6_u(
  201. .i_clk (i_clk),
  202. .i_rst (i_rst),
  203. .i_triger (i_triger),
  204. .i_secteur (i_secteur),
  205. .i_theta (i_theta),
  206. .i_Mi (i_Mi),
  207. .o_cos1 (),
  208. .o_cos2 (),
  209. .o_cos1_samples (),
  210. .o_cos2_samples (),
  211. .o_Ta (),
  212. .o_Tb (),
  213. .o_Tc (),
  214. .o_deadtime1 (S61),
  215. .o_deadtime2 (S62),
  216. .o_deadtime3 (S63),
  217. //test
  218. .A1 (),
  219. .A2 (),
  220. .B1 (),
  221. .B2 (),
  222. .C1 (),
  223. .C2 (),
  224. .CNTs (),
  225. .flag11 (),
  226. .flag12 (),
  227. .flag21 (),
  228. .flag22 (),
  229. .flag31 (),
  230. .flag32 ()
  231. );
  232. reg signed[1:0] o_S1;
  233. reg signed[1:0] o_S2;
  234. reg signed[1:0] o_S3;
  235. always @(posedge i_clk or posedge i_rst)
  236. begin
  237. if(i_rst)
  238. begin
  239. o_S1 <= 2'b00;
  240. o_S2 <= 2'b00;
  241. o_S3 <= 2'b00;
  242. end
  243. else begin
  244. if(i_secteur == 4'd1)
  245. begin
  246. o_S1 <= S11;
  247. o_S2 <= S12;
  248. o_S3 <= S13;
  249. end
  250. if(i_secteur == 4'd2)
  251. begin
  252. o_S1 <= S21;
  253. o_S2 <= S22;
  254. o_S3 <= S23;
  255. end
  256. if(i_secteur == 4'd3)
  257. begin
  258. o_S1 <= S31;
  259. o_S2 <= S32;
  260. o_S3 <= S33;
  261. end
  262. if(i_secteur == 4'd4)
  263. begin
  264. o_S1 <= S41;
  265. o_S2 <= S42;
  266. o_S3 <= S43;
  267. end
  268. if(i_secteur == 4'd5)
  269. begin
  270. o_S1 <= S51;
  271. o_S2 <= S52;
  272. o_S3 <= S53;
  273. end
  274. if(i_secteur == 4'd6)
  275. begin
  276. o_S1 <= S61;
  277. o_S2 <= S62;
  278. o_S3 <= S63;
  279. end
  280. end
  281. end
  282. endmodule

四、仿真结论分析

simulink总体输出波形如下所示:

simulink三个模块分别输出如下所示:

第一个模块输出:

第二个模块输出:

第三个模块输出:

        在QUARTUSII中,调用NCO模块(注意,由于这里是三个cos,所以我们需要将NCO进行相位的延迟,获得三路COS输出)。最后获得如下的效果:

这说明这个部分的内容是正确的。

        也就是通过查找表的方式来实现atan函数的计算过程。这方面,你可以在百度中搜索FPGA反正切查找表计算相关的参考资料。

         这个部分的仿真如下所示:

最后PWM产生波形这个部分的仿真结果如下图所示:

注意,在simulink中,有个参数step,这个参数越小,输出的波形越密集。

整体的仿真效果如下所示:

        上述是整个仿真的输出。由于FPGA是实际硬件的设计,在启动阶段有个初始化的过程,所以一开始的波形会有一个调整阶段,然后进入稳定状态。输出和simulink相同的波形。

五、参考文献

[1]孙文焕, 程善美, 秦忆. 基于FPGA的空间矢量PWM的实现[J]. 电气传动, 2000(06):21-24.A35-16

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/724118
推荐阅读
相关标签
  

闽ICP备14008679号