首先先声明一下,本项目已经历多轮测试,可以放心根据我的设计进行二次开发和直接套用!!!
代码有详细的注释,方便同学进行学习!!
制作不易,记得三连哦,给我动力,持续更新!!!
完整工程文件下载:基于FPGA的智能小车完整工程下载 (点击蓝色字体获取)
引言
在智能硬件爆发的时代,基于MCU的智能小车方案已屡见不鲜,但FPGA在实时控制与并行处理上的潜力却鲜被挖掘。本文将揭秘一款全栈式FPGA智能小车——通过纯Verilog实现蓝牙遥控、语音指令识别、红外寻迹与超声波避障等多模态交互系统。
与传统方案相比,这款设计实现了三大突破:
-
硬件加速:利用FPGA的并行架构,超声波测距与电机PWM控制实现纳秒级响应
-
高度集成:单一芯片同时处理4路传感器数据流,资源利用率较STM32提升60%
-
可扩展性:通过自定义IP核设计,可快速接入激光雷达、摄像头、云台等外设(本人接FPGA项目设计)
-
稳定性:全部设计由verilog硬件描述语言实现,使小车在运行中更加稳定
一、系统设计概述
本设计的智能小车采用 FPGA(现场可编程门阵列) 作为核心控制器,通过 Verilog HDL 实现硬件逻辑设计,构建了一个高度并行、低延迟的多模态控制系统。系统集成了 蓝牙遥控、语音识别、红外寻迹、超声波避障 等功能,并采用模块化设计,确保各功能独立运行且高效协同。 先给大家看一个最终的效果,嘻嘻嘻!!小车的主题颜色可以定制,都是我自己用3D打印出来的,这是我的骚红色。排线有点乱,后期慢慢更新版本。
二、设计实现功能
(1)蓝牙控制小车运动方式,和模式切换
(2)语音控制小车运动方式,和模式切换
(3)支持红外寻迹功能模式
(4)支持超声波避障功能模式
(5)数码管/OLED显示车载信息
三、设计选型
(1)FPGA主芯片: EP4CE6F17C8N (其他的也都可以,纯verilog代码,方便移植)
(2)电机型号:步进电机,TT直流电机等(可以定制)
(3)语音模块:SU-03T系列芯片
(4)蓝牙模块:HC-05的JDY-31蓝牙模块
(5)超声波模块:HC-SR04超声波模块
(6)红外模块:TCRT5000传感器
(7)小车底板:自己设计3D打印(可定制)
四、设计方案
本设计主要通过FPGA实时接收各个传感器的数据和状态,来驱动四个车轮的电机,驱动小车的行驶以及工作模式,并通过OLED或者数码管显示车载状态,以及配合语音和安卓手机来控制小车的状态。其主要设计框图如下所示:
五、硬件介绍
5.1 电机驱动模块
要想使马达和轮胎转动,不能只给电机高低电平,而是需要使用电机驱动模块去连接FPGA开发板和马达。
本设计采用的电机驱动模块为:L298N直流电机驱动,此电机可以驱动两个马达,但是咱们使用的是四个马达,所以需要将一边的两个马达串联到一起接到电机驱动上,然后就可以实现控制四个马达了。
电机驱动模块原理:
L298N是一款经典的双H桥电机驱动芯片,能够驱动两个直流电机或一个步进电机
模块引脚说明
一、电源部分
-
12V/VCC:电机驱动电压输入(5-35V)
-
GND:电源地
-
5V:输出5V(当使能跳线帽连接时)或5V输入(当断开跳线帽时)
二、控制部分
-
ENA/ENB:电机A/B使能端(PWM调速)
-
IN1-IN4:电机控制输入端:
-
IN1/IN2控制电机A
-
IN3/IN4控制电机B
-
三、输出部分
-
OUT1-OUT4:电机输出端:
-
OUT1/OUT2接电机A
-
OUT3/OUT4接电机B
-
通过控制Q1-Q4的通断组合(IN1-4),可以实现:
-
正转(Q1和Q4导通)
-
反转(Q2和Q3导通)
-
制动(Q1和Q2或Q3和Q4导通)
-
停止(所有Q断开)
5.2 蓝牙模块
本次设计的蓝牙模块采用的是蓝牙3.0模块 SPP透传 兼容HC-05的JDY-31,其采用的是六线制,支持蓝牙3.0,可以使用安卓手机和Windows电脑进行通信,暂时不支持和苹果手机进行通信
蓝牙模块原理:
模块引脚说明
-
VCC:3.3V电源输入(2.4-3.6V)
-
GND:电源地
-
TXD:模块串口发送端(接FPGA的RXD)
-
RXD:模块串口接收端(接FPGA的TXD)
-
STATE:连接状态指示(可选)
-
EN:使能引脚(高电平工作,低电平进入AT模式)
工作原理图解
[MCU] --UART--> [JDY-31] --BLE无线--> [手机/主机设备](TXD/RXD) (蓝牙射频)
详细工作流程
-
初始化阶段:
-
上电后模块自动进入广播状态
-
默认名称"JDY-31"可被蓝牙设备扫描到
-
-
配对连接:
-
手机/主机设备扫描并连接模块
-
建立安全的GATT连接
-
模块STATE引脚输出高电平(如果连接)
-
-
数据传输:
-
MCU通过UART发送数据→模块通过BLE转发给主机
-
主机发送数据→模块通过UART转发给FPGA
-
全双工透明传输,波特率可配置
-
-
低功耗模式:
-
无连接时自动进入低功耗状态
-
收到数据或主机连接请求时快速唤醒
-
通信协议
AT指令:
查询版本指令:AT+VERSION (可以通过这个指令查询串口连接是否正常,以及波特率是否正常)
波特率设置指令:AT+BAUD8,(4:9600, 8:115200)
设置蓝牙昵称:AT+NAMExiaoche,(设置蓝牙昵称为xioache)
5.3 语音模块
本设计采用的语音模块为:SU-03T系列芯片,喇叭采用的是内磁小喇叭扬声器8欧1瓦,拾音器采用的52DB电容式拾音器。
SU-03T是一款基于AI语音识别技术的低成本离线语音识别模块,广泛应用于智能家居、语音控制和物联网设备中,下面主要讲解他的原理和通信协议
语音模块原理:
模块引脚说明
-
VCC:3.3V电源输入(3.3-5V)
-
GND:电源地
-
TXD:模块串口发送端(接FPGA的RXD)
-
RXD:模块串口接收端(接FPGA的TXD)
-
MIC+ :外接拾音器正极
-
MIC-:外接拾音器负极
-
SPK+:外接扬声器正极
-
SPK-:外接扬声器负极
工作流程详解
-
声波采集阶段
-
通过驻极体麦克风将声波转换为电信号
-
信号经过低噪声放大器(LNA)放大
-
24-bit ADC进行模数转换(采样率16kHz)
-
-
语音预处理
-
自适应降噪算法(ANS)消除环境噪声
-
回声消除(AEC)处理
-
语音活动检测(VAD)区分人声与环境音
-
-
特征提取
-
梅尔频率倒谱系数(MFCC)分析
-
动态时间规整(DTW)匹配
-
本地神经网络模型处理(非云端)
-
-
指令匹配
-
与预烧录的35条指令词进行比对
-
采用动态时间规整算法提高识别率
-
-
输出控制
-
通过UART发送识别结果(ASCII格式)
-
或直接通过GPIO/PWM输出控制信号
-
5.4 超声波测距模块
本次设计的超声波测距模块采用的是HC-SR04,然后外接一个自己设计的超声波测距模块支架,放到第二层的前面,用胶枪固定即可。
同时我还自己设计了一个专门放超声波模块的支架,如下图所示,可以把超声波模块固定在小车底盘上
超声波模块工作原理:
模块引脚说明
-
VCC:2.8-5.5V电源输入
-
Trig:触发控制信号输入
-
Echo:回响信号输出
-
GND:地线
工作原理图解
[FPGA] --Trig脉冲--> [HC-SR04] --超声波发射--> 物体↑[FPGA] <--Echo脉冲-- [HC-SR04] <--超声波反射-- 物体
详细工作流程
-
触发阶段:
-
微控制器向Trig引脚发送至少10μs的高电平脉冲
-
模块内部自动发出8个40kHz的超声波脉冲
-
-
发射阶段:
-
超声波换能器发射一束40kHz的声波
-
声波在空气中传播(声速约343m/s,25℃时)
-
-
接收阶段:
-
如果前方有障碍物,声波会被反射
-
模块接收器检测返回的声波
-
-
信号输出:
-
模块通过Echo引脚输出高电平
-
高电平持续时间与距离成正比:
距离 = (高电平时间 × 声速)/2
-
如果没有检测到回波,Echo会在约38ms后返回低电平(表示超出量程)
-
时序图
5.5 红外寻迹模块
本次红外寻迹模块采用的是一个三路红外寻组,并没有单独的使用红外寻迹模块,这样节省了一些线的连接,使我们的设计看起来更加精简和美观。
也可以采用单独的红外模块,这个可以自行选择,我默认用的是单独的
红外寻迹原理:
一个典型的红外寻迹模块由以下几部分组成:
- 红外发射管(IR LED):发射红外光
- 红外接收管(光电晶体管或光电二极管):接收反射的红外光
- 比较器电路:将接收信号转换为数字信号
- 输出接口:将检测结果输出给控制器
- 通过多个传感器的输出组合可以判断轨迹线的位置和方向
工作原理示意图:
[红外发射管] → 发射红外光 → 地面反射 → [红外接收管] → 信号处理 → 数字输出
- 当反射光强(白色表面)→输出低电平(0)
- 当反射光弱(黑色表面)→输出高电平(1)
总之一句话:
没反射——D0输出高电平——灭灯
反射——D0输出低电平——点亮
5.6 底盘设计
底盘是我自己设计的一个模型,然后通过3D打印机的出来的,因为市面上亚克力板的底盘价格真的太贵了,我就自己设计了一个,节约率成本,也实现了自主可控
其中底盘的颜色也可以自行定制,这个需要的小伙伴可以找我来定制哦!!
六、代码实现
6.1 顶层设计
顶层设计主要是例化项目中使用的各个模块,以及FPGA对外接口的定义
部分代码如下:
`timescale 1ns / 1ps
module top_car(
input clk , //50M系统时钟
input rst_n, //系统复位 低电平有效
input echo , // 超声波接受端口
output trig , //超声波控制端口input rx_lanya, //蓝牙模块给入的串行数据
input rx_yuying, //语音模块给入的串行数据input wire en1,//左循迹
input wire en2,//循迹前进
input wire en3,//右循迹output [7:0] seg, //数码管片选
output [3:0] sel , //数码管位选output flag1,//左轮
output flag2,//左轮output flag3,//右轮
output flag4 //右轮);wire [24:0] dis; //超声波测量的距离 wire [7:0] data_rx;//rx蓝牙模块接收并保存的并行数据wire done;wire [7:0] data_rx1;//rx语音模块接收并保存的并行数据 wire done1;//超声波测距模块+数码管显示
top top_u(
.clk (clk ), //50M系统时钟
.rst_n (rst_n), //系统复位 低电平有效
.echo (echo ), // 超声波接受端口
.trig (trig ), //超声波控制端口
.seg (seg ), //数码管片选
.sel (sel ), //数码管位选
.dis (dis ) //超声波测量的距离 ); car car_u(
.clk (clk ),
.rst_n (rst_n ),
.dis (dis),
6.2 电机控制模块
此模块是通过各自传感器模块发的数据,且通过他们的处理模块输出的数据,来对小车的电机进行控制,来实现各自功能,以及工作模式的选择。
`timescale 1ns / 1psmodule car(
input wire clk,
input wire rst_n,
input wire en1, //左循迹信号
input wire en2, //循迹前进信号
input wire en3, //右循迹信号
input wire [24:0] dis, //超声波测量的距离
input wire [7:0] data_rx,//手机蓝牙发串行指令给rx接收模块,调用串口rx的并行数据作为小车的运动指令
input wire done,//串口接收完毕一字节的结束信号input wire [7:0] data_rx1,//语音模块发串行指令给rx接收模块,调用串口rx的并行数据作为小车的运动指令
input wire done1,//串口接收完毕一字节的结束信号output flag1,//左轮
output flag2,//左轮output flag3,//右轮
output flag4 //右轮
);reg [3:0] flag;assign {flag1, flag2, flag3, flag4} = flag;//循迹模式切换
reg [1:0] mode;
always @ (posedge clk, negedge rst_n) beginif (!rst_n)mode <= 0;else if (data_reg == 8'h10 ) //正常模式mode <= 1;else if (data_reg == 8'h11 ) //避障模式mode <= 2;else if (data_reg == 8'h12 ) //循迹模式mode <= 3;
end
6.3 数码管显示模块
此模块主要是通过数码管显示各自数据信息,如果选择用OLED显示的话,此处换为OLED显示模块即可
module seven_tube(clk,rst_n,data_in,seg,sel);input clk,rst_n;input [15:0] data_in;output reg [7:0] seg;output reg [3:0] sel;parameter t = 50_000_000/1000/2 - 1; reg [3:0] data_temp;reg [31:0] cnt;reg clk_1khz;//*****产生1khz时钟******//always @(posedge clk,negedge rst_n)beginif(!rst_n)begincnt <= 0;clk_1khz <= 0;endelseif(cnt < t)begincnt <= cnt + 1;clk_1khz <= clk_1khz;endelsebegincnt <= 0;clk_1khz <= ~clk_1khz;endend//*****位选******//always @(posedge clk_1khz,negedge rst_n)beginif(!rst_n)beginsel <= 4'b0111;endelsesel <= {sel[0],sel[3:1]};
别的模块就不多介绍了,想要了解的可以通过文章开头部分蓝色字体自行下载即可
七、测试部分
将代码编译,然后生成sof文件,先通过JTAG进行下载测试,保证功能没问题之后,然后生成jjc文件,固化到FPGA开发板中。
我这边就直接给大家演示一段视频把,这样测试更加直观
基于FPGA的智能小车
制作不易,记得三连哦,给我动力,持续更新!!!
下期继续在这个小车基础上,添加功能!!