什么叫做PWM?借用维基百科的解释就是:脉冲宽度调制(英语:Pulse Width Modulation,缩写:PWM),简称脉宽调制,是将模拟信号变换为脉冲的一种技术,一般变换后脉冲的周期固定,但脉冲的占空比会依模拟信号的大小而改变。
在开关电源中,PWM是作为电压调节的一项重要因素,其控制开关管的导通通过反馈调节以达到稳压的效果。但开关电源的输出都会产生相应的纹波电压,对于高精度的芯片,严重影响其性能。那么如何降低开关电源的纹波呢?可以通过提高PWM的频率来解决问题。普通的开关电源IC一般驱动频率都在2M以下。由此我想到了用FPGA作为PWM的发生器。
下图展示的有相应的逻辑图和Verilog代码
//-----------------------------------------------------------------\//Title: PWM_Driver//Time:2018.9.6//Author:莫见愁//-----------------------------------------------------------------/module Motor_Driver( //system interface input sclk , input rst_n , //Motor Driver interface output Motor_A , output Motor_B , output Motor_C , output Motor_D , //Other interface input Dial_1 , input Dial_2 );//===================================================================\//********************Define interface******************************//===================================================================/ reg [ 0:23] PWM_CNT ;reg Motor_out ;reg Motor_A_reg ;reg Motor_B_reg ;reg Motor_C_reg ;reg Motor_D_reg ;wire Dial_flag_R ;wire Dial_flag_L ;localparam pwm_cnt = 24'd100 ;localparam pwm_comp = 24'd20 ; //===================================================================\//***************************Main Code*****************************//===================================================================/ //计数器always@(posedge sclk or negedge rst_n) if(rst_n==1'b0) PWM_CNT <= 24'd0; else if(PWM_CNT==pwm_cnt-1'd1) PWM_CNT <= 24'd0; else PWM_CNT <= PWM_CNT+1'd1; always@(posedge sclk or negedge rst_n) if(rst_n==1'b0) Motor_out <= 1'd0 ; else if(PWM_CNT>=pwm_comp) Motor_out <= 1'd1 ; else Motor_out <= 1'd0 ; //正反转assign Dial_flag_R = (Dial_1==1'b1) ? 1'd1 : 1'd0 ;assign Dial_flag_L = (Dial_2==1'b1) ? 1'd1 : 1'd0 ;always@(posedge sclk or negedge rst_n) if(rst_n==1'b0) begin Motor_A_reg <= 1'd1 ; Motor_B_reg <= 1'd1 ; Motor_C_reg <= 1'd1 ; Motor_D_reg <= 1'd1 ; end else if(Dial_flag_R==1'b1) begin Motor_A_reg <= Motor_out ; Motor_B_reg <= 1'd1 ; Motor_C_reg <= 1'd1 ; Motor_D_reg <= Motor_out ; end else if(Dial_flag_L==1'b1) begin Motor_A_reg <= 1'd1 ; Motor_B_reg <= Motor_out ; Motor_C_reg <= Motor_out ; Motor_D_reg <= 1'd1 ; end else begin Motor_A_reg <= 1'd1 ; Motor_B_reg <= 1'd1 ; Motor_C_reg <= 1'd1 ; Motor_D_reg <= 1'd1 ; endassign Motor_A=Motor_A_reg;assign Motor_D=Motor_D_reg;assign Motor_B=Motor_B_reg;assign Motor_C=Motor_C_reg;endmodule
|