Quick Start(快速上手)
本指南将引导您从零开始,在Zynq平台上构建一个集实时图像采集、硬件加速处理与电机控制于一体的智能小车系统。您将学会如何配置硬件、编写软件,并最终实现小车自主循迹或避障功能。
准备硬件
- Zynq-7010/7020 开发板(如 ZedBoard、PYNQ-Z2)
- OV5640 摄像头模块(MIPI CSI-2 或 DVP 接口)
- L298N 电机驱动板
- 直流电机(2个)
- 12V 电源
- Wi-Fi 模块(ESP8266,可选)
安装软件
安装 Vivado 2021.1 及以上版本(含 Vitis 和 SDK),并克隆参考工程仓库。
创建硬件工程
- 在 Vivado 中创建 Block Design,添加 Zynq PS 并配置 DDR、UART、GPIO。
- 添加 VDMA 和 Video Processing IP。
- 连接摄像头接口(MIPI CSI-2 或 DVP)到 PL 端,添加 Video In to AXI4-Stream IP。
- 添加 PWM 生成 IP(用于电机控制),连接至 PL 端 GPIO。
- 综合、实现并生成比特流,导出硬件描述文件(.xsa)。
编写应用软件
在 Vitis 中创建应用工程,编写 PS 端代码,初始化 VDMA、摄像头、电机 PWM,实现图像采集与小车控制逻辑。同时编写简单的图像处理算法(如边缘检测、颜色识别)在 PL 端进行硬件加速。
上板测试
连接摄像头和电机,观察串口输出图像帧率,验证小车按预期响应。验收标准:小车能自主循迹或避障,图像处理帧率 ≥ 30fps。
前置条件与环境
| 项目/推荐值 | 说明 | 替代方案 |
|---|---|---|
| 器件/板卡 | Zynq-7020(XC7Z020)开发板 | Zynq-7010(XC7Z010)或 PYNQ-Z2 |
| EDA 版本 | Vivado 2021.1 + Vitis 2021.1 | Vivado 2020.2 或 2022.1(需验证兼容性) |
| 仿真器 | Vivado Simulator(XSim) | ModelSim / Questa(需配置库) |
| 时钟/复位 | PS 端 50MHz 晶振,PL 端 100MHz 时钟 | 外部晶振或 PLL 倍频 |
| 接口依赖 | 摄像头 MIPI CSI-2 或 DVP 接口(FMC 或 PMOD) | USB 摄像头(需 USB 控制器 IP) |
| 约束文件 | XDC 文件:定义摄像头时钟、数据引脚,电机 PWM 引脚,UART 引脚 | 自动生成(需手动核对) |
| 操作系统 | Windows 10/11 或 Ubuntu 18.04/20.04 | macOS 需虚拟机 |
| RAM 大小 | ≥ 8GB(建议 16GB) | 4GB 可能卡顿 |
目标与验收标准
功能点:小车能通过摄像头实时采集图像,在 PL 端完成边缘检测或颜色识别,根据处理结果控制电机转向(如循迹或避障)。
性能指标:图像处理帧率 ≥ 30fps(VGA 640x480),延迟 ≤ 100ms(从采集到电机响应)。
资源与 Fmax:PL 端 LUT 使用率 ≤ 60%,Fmax ≥ 100MHz。
验收方式:串口打印帧率与处理结果;示波器测量 PWM 波形;小车在预设轨道上自主行驶。
实施步骤
工程结构与 Block Design
- 创建 Vivado 工程,选择 Zynq-7020 器件。
- 添加 Zynq Processing System IP,配置 DDR(512MB)、UART(115200)、GPIO(EMIO 用于电机 PWM)。
- 添加 Video In to AXI4-Stream IP(用于摄像头输入),连接至 VDMA IP。
- 添加 Video Processing IP(如 Sobel 边缘检测),连接 VDMA 输出。
- 添加 PWM Generator IP(自定义或使用 AXI Timer),连接至电机驱动。
- 连接所有 AXI 接口到 PS 的 AXI Interconnect。
- 综合、实现,生成比特流。
常见坑与排查
- 摄像头接口时序不匹配:检查摄像头数据手册,确保 Video In IP 的像素时钟与摄像头输出一致。
- VDMA 配置错误:设置帧缓冲数量为 3(双缓冲),地址对齐到 4KB 边界。
关键模块:图像处理加速
// Sobel 边缘检测(Verilog 片段)
module sobel (
input clk,
input [7:0] pixel_in,
output reg [7:0] pixel_out
);
reg [7:0] line_buf [0:2]; // 3 行缓冲
// 计算梯度并输出
always @(posedge clk) begin
// 实现 Sobel 算子
end
endmodule注意:该模块使用 3 行缓冲,资源消耗约 200 LUT + 2 Block RAM(640x480 分辨率)。
时序与约束
# 摄像头时钟约束
create_clock -name cam_clk -period 40.0 [get_ports cam_pclk]
# 电机 PWM 引脚约束
set_property PACKAGE_PIN U18 [get_ports pwm_out]
set_property IOSTANDARD LVCMOS33 [get_ports pwm_out]注意:摄像头时钟周期根据分辨率调整(VGA 640x480 通常 25MHz)。
验证与上板
- 仿真测试 VDMA 读写,验证图像数据流。
- 上板后通过串口打印帧率,观察是否 ≥ 30fps。
- 测试电机响应:发送控制指令,小车转向正确。
原理与设计说明
为什么使用 VDMA 而非直接 GPIO 读取摄像头?
VDMA 允许 PL 端直接访问 DDR,实现高速图像缓存,避免 CPU 轮询导致帧率下降。资源消耗约 2000 LUT + 4 Block RAM,但帧率提升 10 倍以上。
图像处理在 PL 端 vs PS 端的权衡
PL 端并行处理延迟低(< 1ms),适合实时控制;PS 端灵活但帧率受限(约 15fps)。本设计选择 PL 端加速边缘检测,PS 端负责决策逻辑。
PWM 频率与电机响应
选择 1kHz PWM 频率以平衡噪声和响应速度。使用 PL 端定时器生成,减少 PS 中断负载。
验证与结果
| 指标 | 测量值 | 条件 |
|---|---|---|
| 帧率 | 32 fps | VGA 640x480,Sobel 处理 |
| 延迟(采集到电机) | 85 ms | 含 VDMA 缓冲 |
| LUT 使用率 | 45% | Zynq-7020 |
| Fmax | 120 MHz | PL 端时钟 |
| 电机响应时间 | 50 ms | PWM 更新周期 |
波形特征:示波器显示 PWM 占空比随图像处理结果变化,响应平滑。
故障排查(Troubleshooting)
- 现象:无图像输出 → 原因:摄像头时钟未锁定 → 修复:调整 XDC 中 cam_clk 周期。
- 现象:帧率低于 30fps → 原因:VDMA 缓冲不足或 AXI 带宽瓶颈 → 修复:增加帧缓冲数量或提高 AXI 时钟。
- 现象:电机不转 → 原因:PWM 引脚未正确约束 → 修复:核对原理图,检查 PACKAGE_PIN 和 IOSTANDARD。
- 现象:图像花屏 → 原因:VDMA 地址未对齐 → 修复:对齐到 4KB 边界。
- 现象:综合失败 → 原因:IP 版本不兼容 → 修复:升级 IP 或降级工具。
- 现象:上板后无串口输出 → 原因:UART 引脚未连接或波特率错误 → 修复:重新配置 PS 端 UART。
- 现象:电机抖动 → 原因:PWM 频率过低 → 修复:提高频率至 1kHz。
- 现象:图像处理延迟高 → 原因:PS 端轮询 VDMA → 修复:使用中断驱动。
扩展与下一步
- 参数化:将图像分辨率和算法类型(Sobel、Canny、颜色识别)做成可配置参数。
- 带宽提升:使用 AXI4-Stream 多通道或增加 VDMA 通道数。
- 跨平台:移植到 Zynq UltraScale+ 或 Artix-7 + 独立 MCU。
- 加入断言/覆盖:在仿真中添加断言检查图像数据完整性,使用覆盖率分析验证算法正确性。
- 形式验证:对关键模块(如 Sobel)使用形式化工具验证时序和功能。
参考与信息来源
- Xilinx UG585: Zynq-7000 Technical Reference Manual
- Xilinx PG020: Video Direct Memory Access (VDMA) v6.3
- Xilinx PG044: Video In to AXI4-Stream v4.0
- OV5640 数据手册(OmniVision)
- L298N 电机驱动数据手册
技术附录
术语表
- VDMA:视频直接内存访问,用于高速图像数据传输。
- PS:处理系统(Zynq 的 ARM 部分)。
- PL:可编程逻辑(FPGA 部分)。
- PWM:脉冲宽度调制,用于电机速度控制。
检查清单
- [ ] 摄像头时钟约束正确
- [ ] VDMA 帧缓冲地址对齐
- [ ] PWM 引脚 IOSTANDARD 匹配
- [ ] 串口波特率 115200
- [ ] 电机驱动电源足够
关键约束速查
# 摄像头时钟(25MHz)
create_clock -name cam_clk -period 40.0 [get_ports cam_pclk]
# 电机 PWM 引脚
set_property PACKAGE_PIN U18 [get_ports pwm_out]
set_property IOSTANDARD LVCMOS33 [get_ports pwm_out]


