4—基于FPGA(ZYNQ-Z2)的多功能小车—软件设计—电机驱动模块

我使用的FPGA是Xilinx的PYNQ-7020(ZYNQ-Z2),在Vivado2018.3平台使用Verilog进行编程。

目录

1.电机驱动介绍:

 2.模块编写介绍:

2.1 Verilog代码

2.2 方向逻辑分析

2.4PWM_Divider模块

 3. 调用方法


1.电机驱动介绍:

使用TB6612FNG电机驱动,驱动一个电机需要FPGA对芯片有3个输入:

IN1 控制正反转
IN2 控制正反转
PWM 控制转速

  IN1 IN2控制转向的逻辑如下:

IN1 IN2 转向
1 0 正转
0 1 反转
0 0 不转

 2.模块编写介绍:

对于电机控制模块,我们需要输入的有:

  ①运动方向(mode)——0停止,1前进,2后退,3左转,4右转

  ②行驶速度(pwm)——0-255,越大速度越快

  ③系统时钟(clk)和复位按钮(reset)


2.1 Verilog代码

module Four_Wheel_Control (
  input wire clk,           // 系统时钟输入
  input wire reset,         // 复位按键输入
  input wire [4:0] mode,    // 运动模式输入(0-停止,1-前进,2-后退,3-左转,4-右转)
  input wire [7:0] pwm,     // PWM值输入(0-255范围)
  output wire motor_A_PWM,  // 电机A的PWM控制信号输出
  output wire motor_A_IN1,  // 电机A的IN1控制信号输出
  output wire motor_A_IN2,  // 电机A的IN2控制信号输出
  output wire motor_B_PWM,  // 电机B的PWM控制信号输出
  output wire motor_B_IN1,  // 电机B的IN1控制信号输出
  output wire motor_B_IN2,  // 电机B的IN2控制信号输出
  output wire motor_C_PWM,  // 电机C的PWM控制信号输出
  output wire motor_C_IN1,  // 电机C的IN1控制信号输出
  output wire motor_C_IN2,  // 电机C的IN2控制信号输出
  output wire motor_D_PWM,  // 电机D的PWM控制信号输出
  output wire motor_D_IN1,  // 电机D的IN1控制信号输出
  output wire motor_D_IN2   // 电机D的IN2控制信号输出
);

  wire direction_A, direction_B, direction_C, direction_D;

  // 方向控制逻辑
// 方向控制逻辑
assign direction_A = (mode == 1 || mode == 3) ? 0 : 1;  // 前进和左转为正向,其他为反向
assign direction_B = (mode == 1 || mode == 3) ? 0 : 1;
assign direction_C = (mode == 1 || mode == 4) ? 0 : 1;  // 前进和右转为正向,其他为反向
assign direction_D = (mode == 1 || mode == 4) ? 0 : 1;


  // 实例化PWM分频模块
  PWM_Divider pwm_A_divider (
    .clk(clk),
    .reset(reset),
    .duty(pwm),
    .pwm(motor_A_PWM)
  );

  PWM_Divider pwm_B_divider (
    .clk(clk),
    .reset(reset),
    .duty(pwm),
    .pwm(motor_B_PWM)
  );

  PWM_Divider pwm_C_divider (
    .clk(clk),
    .reset(reset),
    .duty(pwm),
    .pwm(motor_C_PWM)
  );

  PWM_Divider pwm_D_divider (
    .clk(clk),
    .reset(reset),
    .duty(pwm),
    .pwm(motor_D_PWM)
  );

  // 输出电机方向和转向信号
  assign motor_A_IN1 = direction_A;
  assign motor_A_IN2 = ~direction_A;
  assign motor_B_IN1 = direction_B;
  assign motor_B_IN2 = ~direction_B;
  assign motor_C_IN1 = direction_C;
  assign motor_C_IN2 = ~direction_C;
  assign motor_D_IN1 = direction_D;
  assign motor_D_IN2 = ~direction_D;

endmodule

2.2 方向逻辑分析

  其中比较难理解的是方向逻辑,其中AC一组,BD一组

  如果mode等于1或3,direction_A和direction_B被设置为0,表示正向(例如前进或左转)。

  如果mode等于1或4,direction_C和direction_D被设置为0,表示正向(例如前进或右转)。

  对于其他mode值,direction_A、direction_B、direction_C和direction_D被设置为1,表示反向。

模式(mode) direction_A direction_B direction_C direction_D 实际功能
0 1 1 1 1 后退
1 0 0 0 0 前进
2 1 1 1 1 后退
3 0 0 1 1 左转
4 1 1 0 0 右转

逻辑真值表

其中我们可以发现一个问题:mode=0时是后退而不是停止。因此,在主模块中,如果mode=0,我们可以将pwm≤0,这就实现了停止。


2.4PWM_Divider模块

  counter在0-255之间不断累加重置,当counterpwm时输出低电平。这样就实现了PWM。

module PWM_Divider (
  input wire clk,        // 系统时钟输入
  input wire reset,      // 复位按键输入
  input wire [7:0] duty, // 占空比输入(0-255范围)
  output reg pwm         // PWM输出
);

  reg [7:0] counter;

  always @(posedge clk or posedge reset) begin
    if (reset)
      counter <= 0;
    else if (counter >= 255)
      counter <= 0;
    else
      counter <= counter + 1;
  end

  always @(posedge clk) begin
    if (reset)
      pwm <= 0;
    else if (counter < duty)
      pwm <= 1;
    else
      pwm <= 0;
  end

endmodule

  第一个always块是一个组合逻辑块,它根据时钟上升沿和复位信号的状态更新计数器的值。如果复位信号为高电平,计数器被重置为0。如果计数器的值大于等于255,它会被重置为0。否则,计数器的值递增1。

  第二个always块是一个时序逻辑块,它在每个时钟上升沿时根据计数器和占空比的比较更新PWM输出的值。如果复位信号为高电平,PWM输出被强制为低电平(0)。如果计数器的值小于占空比(duty),PWM输出被设置为高电平(1)。否则,PWM输出被设置为低电平(0)。


 3. 调用方法

在主模块中实例化Four_Wheel_Control模块,在always块中通过调整模式与占空比,就能够实现电机的实时控制。

具体结构如下:

4—基于FPGA(ZYNQ-Z2)的多功能小车—软件设计—电机驱动模块_第1张图片

 

你可能感兴趣的:(fpga开发)