名称:正弦波脉宽调制SPWM波形发生器verilog语言basys3开发板(代码在文末下载)
软件:VIVADO
语言:Verilog
代码功能:
SPWM技术即为正弦脉宽调制技术。就是通过使用具有正弦规律变化的PWM波来模拟正弦波的技术。其原理就是通过一个载波(一般可以选用等腰三角波作为载波)加载一个调制波(即需要模拟的正弦波)将二者叠加后在波形相交位置通过冲量相等原理,即化为等幅不等宽(或者等宽不等幅)的方波(等幅不等宽--这些方波的宽度即占空比按照正弦波规律变化)来输出调制后的正弦波。这样的PWM波输出来是占空比按照正弦波规律变化的波形即为SPWM波形
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
本代码已在Basys3开发板验证,开发板如下,其他开发板可以修改管脚适配:
演示视频:
设计文档:
1. SPWM原理
SPWM技术即为正弦脉宽调制技术。就是通过使用具有正弦规律变化的PWM波来模拟正弦波的技术。其原理就是通过一个载波(一般可以选用等腰三角波作为载波)加载一个调制波(即需要模拟的正弦波)将二者叠加后在波形相交位置通过冲量相等原理,即化为等幅不等宽(或者等宽不等幅)的方波(等幅不等宽--这些方波的宽度即占空比按照正弦波规律变化)来输出调制后的正弦波。这样的PWM波输出来是占空比按照正弦波规律变化的波形即为SPWM波形
2. 工程文件
3. 程序文件
4. 管脚约束
5. 程序运行
6. Testbench
7. 仿真图
部分代码展示:
module?SPWM( ????input?clk_100M, ????output?SPWM_out, ????output?SPWM_out_ant ????); reg?[4?:?0]?addra_sanjiao=5'd0; wire?[7?:?0]?douta_sanjiao; //三角波 sanjiao_32?sanjiao_32_U?( ??.clka(clk_100M),????//?input?wire?clka ??.addra(addra_sanjiao),??//?input?wire?[4?:?0]?addra ??.douta(douta_sanjiao)??//?output?wire?[7?:?0]?douta ); reg?[8?:?0]?addra_sin=5'd0; wire?[7?:?0]?douta_sin; //正弦波 wire?sin_clk;//根据sin_clk调整sin波输出波形 //sin_512?sin_512_U?( //??.clka(sin_clk),????//?input?wire?clka //??.addra(addra_sin),??//?input?wire?[8?:?0]?addra //??.douta(douta_sin)??//?output?wire?[7?:?0]?douta //); sin_512?sin_512_U?( ??.clka(sin_clk),????//?input?wire?clka ??.ena(1'b1),??????//?input?wire?ena ??.addra(addra_sin),??//?input?wire?[8?:?0]?addra ??.douta(douta_sin)??//?output?wire?[7?:?0]?douta ); //要求输出正弦波频率1=10K,频率2=12K //由于正弦波ROM由512个点组成,所以sin_clk_1=512*10K=5120K,sin_clk_2=512*12K=6144K reg?sin_clk_1=0; reg?sin_clk_2=0; //100M分频为5120K和6144K //分频19和16 reg?[7:0]?count_1=8'd0; reg?[7:0]?count_2=8'd0; //计数分频 always@(posedge?clk_100M) ????if(count_1==8'd18) ????????count_1<=8'd0; ????else ????????count_1<=count_1+8'd1; always@(posedge?clk_100M) ????if(count_1>8'd9) ????????sin_clk_1<=1; ????else ????????sin_clk_1<=0; always@(posedge?clk_100M) ????if(count_2==8'd15) ????????count_2<=8'd0; ????else ????????count_2<=count_2+8'd1; always@(posedge?clk_100M) ????if(count_2>8'd7) ????????sin_clk_2<=1; ????else ????????sin_clk_2<=0; //ROM地址加1 always@(posedge?clk_100M) ????begin ????????addra_sanjiao<=addra_sanjiao+1; ????end always@(posedge?sin_clk) ????begin ????????addra_sin<=addra_sin+1; ????end ???? //产生SPWM波, reg?PWM_wave=0;??????? always@(posedge?clk_100M)
1338