名稱:正弦波脈寬調(diào)制SPWM波形發(fā)生器verilog語言basys3開發(fā)板(代碼在文末下載)
軟件:VIVADO
語言:Verilog
代碼功能:
SPWM技術(shù)即為正弦脈寬調(diào)制技術(shù)。就是通過使用具有正弦規(guī)律變化的PWM波來模擬正弦波的技術(shù)。其原理就是通過一個(gè)載波(一般可以選用等腰三角波作為載波)加載一個(gè)調(diào)制波(即需要模擬的正弦波)將二者疊加后在波形相交位置通過沖量相等原理,即化為等幅不等寬(或者等寬不等幅)的方波(等幅不等寬--這些方波的寬度即占空比按照正弦波規(guī)律變化)來輸出調(diào)制后的正弦波。這樣的PWM波輸出來是占空比按照正弦波規(guī)律變化的波形即為SPWM波形
FPGA代碼Verilog/VHDL代碼資源下載:www.hdlcode.com
本代碼已在Basys3開發(fā)板驗(yàn)證,開發(fā)板如下,其他開發(fā)板可以修改管腳適配:
演示視頻:
設(shè)計(jì)文檔:
1. SPWM原理
SPWM技術(shù)即為正弦脈寬調(diào)制技術(shù)。就是通過使用具有正弦規(guī)律變化的PWM波來模擬正弦波的技術(shù)。其原理就是通過一個(gè)載波(一般可以選用等腰三角波作為載波)加載一個(gè)調(diào)制波(即需要模擬的正弦波)將二者疊加后在波形相交位置通過沖量相等原理,即化為等幅不等寬(或者等寬不等幅)的方波(等幅不等寬--這些方波的寬度即占空比按照正弦波規(guī)律變化)來輸出調(diào)制后的正弦波。這樣的PWM波輸出來是占空比按照正弦波規(guī)律變化的波形即為SPWM波形
2. 工程文件
3. 程序文件
4. 管腳約束
5. 程序運(yùn)行
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;//根據(jù)sin_clk調(diào)整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個(gè)點(diǎn)組成,所以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; //計(jì)數(shù)分頻 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 ???? //產(chǎn)生SPWM波, reg?PWM_wave=0;??????? always@(posedge?clk_100M)