用verilog实现L293D 驱动板接口

课程实验做了一个蓝牙智能小车,nexys4开发板,MIPSfpga(一个在 FPGA 上实现的商业 MIPS 处理器软核,Imagination Technologies公司提供给高校免费使用),再加上vivado里面的一些IP核,搭了一个简单的处理器系统。要用这玩意来接用了L293D 驱动板的小车,网上绝大多数资料都是用arduino来接L293D驱动板,所以找了一下也没有轮子拿来用,就自己写一个咯。L293D驱动板的资料你可以在网上找到很多,而且它的功能远不止我这里的控制一个四驱的小车,这里我就不细说了。
首先呢,看驱动板的信号线,接线可以参考这篇,使用L293D驱动板(for Arduino)对电动机进行驱动

引脚 名称 功能
3 Pwm2B PWM调速
4 Dir_clk 串锁器串行输入时钟
5 Pwm0B PWM调速
6 Pwm0A PWM调速
7 Dir_enable 串锁器使能
8 Dir_serial 串锁器串行输入
11 Pwm2A PWM调速
12 Dir_latch 串锁器使能
24(另一边) GND 逻辑地
25(24的旁边) VCC_logic 逻辑正

上面名字估计叫法还不一样,但是从名字也能看出来这块板子大概是啥结构。四个PWM调速是两块L293D芯片的输入,原理也自己去查吧,不要调速给个逻辑1也是可以的。另外几个串锁器( 74HCT595N 芯片,估计名字也不统一)信号,其实就是一个移位寄存器、一个锁存器和一个三态门构成,八位,每两位组合控制一个马达的转向。所以我们要实现的接口主要相当于一个串行通信的东西,把CPU传来的8位并行控制位按串行的方式写到74HCT595N 芯片的移位寄存器中,然后Dir_latch给个上升沿把数据锁存到锁存器中,最后Dir_enable给低电平,使能三态门,一次控制就算完成了,直到下次控制写入之前小车都会按照上次写的信号运转。
前面说的CPU用的是AXI4总线,所以我就也封装了一个基于AXI4总线的IP核,内部逻辑很简单:分频(可能需要,整个板子上用的是100MHz或者50MHz的时钟,对串行传输数据来说可能有点快)、传数据。
传数据这块的代码在下面,用verilog也是个生手,可能写的不太优雅。

`timescale 1ns / 1ps

module Car_Driver_Int (
input Clk,
    input [31:0] CtrlSig,
    output reg DIR_serial,
    output reg DIR_enable,
    output reg DIR_latch
);
    parameter ST0 = 0, ST1 = 1, ST2 = 2, ST3 = 3, ST4 = 4, ST5 = 5, ST6 = 6, ST7 = 7, ST8 = 8;
    reg [3: 0] p_state = ST8;
    reg [31:0] buff = 0;

    always @ (negedge Clk)
        case (p_state)
            ST0:
                begin
                    buff <= CtrlSig;
                    p_state <= ST1;
                    DIR_serial <= CtrlSig[0];
                    DIR_enable <= 1;
                    DIR_latch  <= 0;
                end
            ST1:
                begin
                    p_state <= ST2;
                    DIR_serial <= CtrlSig[1];
                    DIR_enable <= 1;
                    DIR_latch  <= 0;
                end
            ST2:
                begin
                    p_state <= ST3;
                    DIR_serial <= CtrlSig[2];
                    DIR_enable <= 1;
                    DIR_latch  <= 0;
                end
            ST3:
                begin
                    p_state <= ST4;
                    DIR_serial <= CtrlSig[3];
                    DIR_enable <= 1;
                    DIR_latch  <= 0;
                end
            ST4:
                begin
                    p_state <= ST5;
                    DIR_serial <= CtrlSig[4];
                    DIR_enable <= 1;
                    DIR_latch  <= 0;
                end
            ST5:
                begin
                    p_state <= ST6;
                    DIR_serial <= CtrlSig[5];
                    DIR_enable <= 1;
                    DIR_latch  <= 0;
                end
            ST6:
                begin
                    p_state <= ST7;
                    DIR_serial <= CtrlSig[6];
                    DIR_enable <= 1;
                    DIR_latch  <= 0;
                end
            ST7:
                begin
                    p_state <= ST8;
                    DIR_serial <= CtrlSig[7];
                    DIR_enable <= 1;
                    DIR_latch  <= 0;
                end
            ST8:
                begin
                    p_state =  !(CtrlSig ^ buff) ? ST8 : ST0;
                    DIR_serial <= CtrlSig[7];
                    DIR_enable <= 0;
                    DIR_latch  <= 1;
                end
            default:
                begin
                    p_state <= ST8;
                end
        endcase
endmodule

为了确定啥时候进行下次传输,所以把上次写的内容存了下来,一但和总线里的数据不一样就传,传完更新存的值。也可以用AXI总线的信号来控制这个,方法很多。不过看74HCT595N文档说这块芯片是标准的SPI,vivado里面有SPI的IP核,但是我一直没能接好~_~。

你可能感兴趣的:(CPU)