dameihuaxia 发表于 2019-12-6 08:53:49

FPAGA直流电机PWM控制

下面是控制电路



    当motor_a是高电平时,Q3,Q1,Q5导通,A端位高电平,B端为低电平,直流电机正转;由于Q5的集电极通过一个二极管连接到H桥的另外一个控制端motor_b,将motor_b的电压钳在1.0V以下,所以,不管motor_b输出高电平还是地电平,Q6、Q4、Q2都会截止,不会造成H桥短路;

   当motor_a是低电平时,Q3,Q1,Q5截止,motor_b输出的电平可以控制电机的反转或停机。当motor_b输出高电平时,Q6,Q4,Q2导通,A端为低电平,B端为高电平,电机反转;当motor_b输出为低电平时,Q6,Q4,Q2截止;电机停机;


//程序实现的功能:利用FPGA产生PWM技术来控制直流电机的停、起;正、反转;加减速
module dc_motor
      (
       clk,
       rst_n,
       key1,
       key2,
       key3,
       motor_a,
       motor_b
      );

input       clk;       //系统时钟 50MHZ;
input       rst_n;   //复位信号,低电平有效;
input       key1;      //控制电机加速、减速;
input       key2;      //控制电机启、停;
input       key3;      //控制电机正、反转;
output      motor_a;   //直流电机的两个控制端;
output      motor_b;   

wire duty_ratio ;      //占空比,
wire pwm_out    ;         //pwm输出;
wire pwm_en;                //pwm使能信号;

pwm      pwm
         (
          .clk(clk),
          .rst_n(rst_n),
          .duty_ratio(duty_ratio),
          .pwm_en(pwm_en),
          .pwm_out(pwm_out)

         );

motor_control   motor_control
         (
             .clk(clk),
             .rst_n(rst_n),
             .key1(key1),
             .key2(key2),
             .key3(key3),
             .pwm_in(pwm_out),
             .duty_ratio(duty_ratio),
             .pwm_en(pwm_en),
             .motor_a(motor_a),
             .motor_b(motor_b)
                     
         );

            
endmodule         


module pwm
    (
      clk,
      rst_n,
      pwm_en,
      duty_ratio,
      pwm_out
      
    );

input   clk;      
input   rst_n;
input   pwm_en;       //pwm使能信号;
inputduty_ratio;   //占空比;
output    pwm_out;      //pwm输出;

reg cnt;      //PWM内部计数器;
always @(posedge clk or negedge rst_n)
begin
      if(!rst_n)
      cnt<=16'd0;
      else if(pwm_en)
      cnt<=cnt+1'b1;
end

reg pwm_out_r;
always @ (posedge clk or negedge rst_n)
begin
      if(!rst_n)
         pwm_out_r<=1'b0;
      else if((pwm_en)&&(cnt<=duty_ratio))
         pwm_out_r<=1'b1;
      else
         pwm_out_r<=1'b0;   
end

assign pwm_out=pwm_out_r;
endmodule   

module motor_control
      (
         clk,
         rst_n,
         key1,
         key2,
         key3,
         pwm_in,
         pwm_en,
         duty_ratio,
         motor_a,
         motor_b
         
      );

input      clk;         //系统时钟 50MHZ;
input      rst_n;         //复位信号,低电平有效;
input      key1;          //控制电机加速、减速;
input      key2;          //控制电机启、停;
input      key3;          //控制电机正、反转;
input      pwm_in;      //pwm输入;
output   pwm_en;      //pwm使能;
outputduty_ratio;    //占空比;
output   motor_a;       //直流电机的两个控制端;
output   motor_b;      

//键盘消抖;
reg key_r1;
always @ (posedge clkor negedge rst_n)
begin
       if(!rst_n)
         key_r1<=3'b111;
       else
      key_r1<={key1,key2,key3} ;
end
      
reg key_r2;
always @ (posedge clk or negedge rst_n)
begin
       if(!rst_n)
         key_r2<=3'b111;
       else
      key_r2<=key_r1;
end

wire neg_key1;
assign neg_key1=(~key_r1)&key_r2;    // 脉冲下降沿检测;

reg    time_cnt;   
always @(posedge clk or negedge rst_n)
begin
       if(!rst_n)
          time_cnt<=20'd0;
       else if(neg_key1)      //检测到有按键按下,延时20ms;
         time_cnt<=20'd0;
       else
         time_cnt<=time_cnt+1'b1;   
end

reg key_r3;
always @(posedge clk or negedge rst_n)
begin
      if(!rst_n)
         key_r3<=3'b111;
      else if(time_cnt==20'hfffff)    //延时20ms后再次检测;
         key_r3<={key1,key2,key3};
end

reg key_r4;
always @ (posedge clkor negedge rst_n)
begin
       if(!rst_n)
         key_r4<=3'b111;
       else
      key_r4<=key_r3;
end

wire neg_key2;
assign neg_key2=(~key_r3)&(key_r4);

//控制电机;

regduty_ratio_r;
always @ (posedge clk or negedge rst_n)
begin
       if(!rst_n)
         duty_ratio_r<=4'd0;
       else if(neg_key2)
         duty_ratio_r<=duty_ratio+1'b1;       //电机加减速;
end

assign duty_ratio=duty_ratio_r;

reg pwm_en_r;
always @ (posedge clk or negedge rst_n)
begin
       if(!rst_n)
         pwm_en_r<=1'b0;
      else if(neg_key2)                  //电机停起;
         pwm_en_r=~pwm_en_r;
end

assignpwm_en=pwm_en_r;

reg motor_dir;
always @ (posedge clk or negedge rst_n)
begin
   if(!rst_n)
       motor_dir<=1'b0;
   else if(neg_key2)
       motor_dir<=~motor_dir;            //电机正反转;
end
   
assignmotor_a=motor_dir? pwm_in:1'b0;
assignmotor_b=motor_dir? 1'b0:pwm_in;
   
endmodule

zhangyukun 发表于 2019-12-6 14:13:20

FPAGA直流电机PWM控制

lixirui 发表于 2019-12-6 15:32:39

FPAGA直流电机PWM控制

雷磊 发表于 2019-12-30 09:36:42


FPAGA直流电机PWM控制
页: [1]
查看完整版本: FPAGA直流电机PWM控制