课程实验做了一个蓝牙智能小车,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核,但是我一直没能接好~_~。