
简介这是一套围绕SDR软件无线电与嵌入式应用的开发板配套资料聚焦ZYNQ7020AD9361STM32联合方案覆盖FPGA逻辑、STM32控制与AD9361射频收发链路三个层面。整包共11个文件包括6个txt解析文档、3张png原理图与界面截图、1个html说明页面及1个doc文档压缩包仅38KB内容精炼集中、便于快速查阅。目前已有211人学习下载。价值在于资源从硬件原理图设计、接口定义、代码框架到信号处理思路均有涉及图文结合展示开发板结构可帮助无线通信工程师、硬件开发者和高校研究者理解SDR平台的软硬件协同设计流程同时附赠的FPGA数字图像处理资料为将同一开发板扩展至图像采集、边缘处理等方向提供了可行参考适合入门学习与项目预研。 拿到一块 ZYNQ7020 AD9361 的 SDR 软件无线电开发板盒子里的料还不少FPGA 源码、STM32 工程、原理图、PCB外加一份“FPGA 数字图像处理资料”。这种组合在 SDR 圈子里其实非常典型但真上手就会发现它和单纯玩 STM32 或者单纯写 FPGA 逻辑完全是两码事。ZYNQ 的双核 ARM 和可编程逻辑要协同AD9361 的射频收发链路要配置STM32 还得在边上干点控制活三套体系叠在一起资料再多也容易看得头晕。这篇文章我就以实际使用这套板子的经验为线索把架构思路、代码分工、资料阅读顺序、典型应用和移植验证踩过的坑一次性说清楚。不管是刚接触 SDR 的嵌入式工程师还是准备拿 FPGA 做信号处理的学生又或是想把这套板子改造成自定义无线电平台的老手应该都能从这里找到可以直接上手的方法。1. ZYNQ7020AD9361 这套 SDR 板卡先拆清楚谁在干活1.1 三个核心芯片的角色划分很多初学者拿到板子第一件事就是打开原理图然后被满屏的 DDR3、LVDS、SPI、JTAG 绕晕。我的建议是先把三个核心器件的关系搞清楚。AD9361 是整套系统的射频前端负责把空中 70MHz 到 6GHz 的模拟信号变成数字 IQ 数据。它内部集成了 LNA、混频器、可调滤波器、12 位 ADC/DAC甚至还有 DDC/DUC数字下变频/上变频和抽取/插值滤波器。换句话说从天线进来的信号经过它之后直接输出的就是基带 IQ 采样数据频率范围、增益、带宽都通过 SPI 寄存器配置。ZYNQ7020 是这套板子的数字大脑具体型号一般是 XC7Z020。它分为 PSProcessing System双核 ARM Cortex-A9和 PLProgrammable Logic等效 Kintex-7 级别的 FPGA 资源两半。PL 负责处理 AD9361 送过来的高速 IQ 数据流比如滤波、解调、FFT、DDR3 缓存等PS 负责跑 Linux 系统、网络协议栈、用户交互界面以及通过 AXI 总线配置 PL 端的寄存器。STM32 在不少低成本 SDR 板子上是作为“辅助控制角色”出现的。AD9361 的 SPI 配置、电源时序、前端开关切换、LED 指示、按键扫描这类低频操作放在 STM32 里做很合适。ZYNQ 的 PS 侧即使能跑 Linux启动时间也比 STM32 长而且把所有控制逻辑都压在 PS 上会让系统耦合度变高。STM32 的存在能让 ZYNQ 专注于数据面控制面单独走一条简单可靠的链路。1.2 为什么 SDR 方案绕不开“PSPL射频前端”这套组合以前做无线电设备通常是 MCU 专用基带芯片或者 DSP 射频芯片功能固化想改个调制方式就得重新画板子。SDR 的核心思想是把尽可能多的信号处理放到可编程的数字域里完成射频前端只负责信号频率搬移和数字化剩下的都是代码的事。ZYNQ7020 的价值在于它把“通用处理器”和“可编程逻辑”放在了同一颗芯片里。PL 侧可以并行处理几十路高速数据流非常适合做 FFT、CIC 滤波、DDS、数据打包这类任务PS 侧又能跑完整的操作系统处理网络协议、文件存储、人机交互。AD9361 把射频到基带的距离拉得极短频率覆盖范围又宽两者一组合就是一个“硬件通用、功能靠软件定义”的完整无线电平台。2. FPGASTM32 双芯分工第一版固件该这么搭2.1 AD9361 的 SPI 配置链路到底该放在哪一侧这是最容易纠结的问题。AD9361 上电后默认状态是收不到信号的必须完成初始化配置设置本振频率、信道带宽、增益模式、数据接口格式、校准等。这些寄存器数量上百个配置顺序还有讲究。我实测下来用 STM32 做 AD9361 初始化是最省事的方案。原因有几点第一STM32 的 SPI 外设成熟稳定HAL 库几行代码就能读写寄存器调试也方便第二AD9361 初始化是慢速控制操作不需要 ZYNQ 的高速总线介入第三STM32 可以先于 ZYNQ 完成射频链路上电和配置等 ZYNQ 启动完AD9361 已经处于可工作状态时序上更好把控。如果用 ZYNQ PS 侧来配 AD9361 也可以尤其是跑 Linux 时ADI 官方提供了libad9361-iio驱动框架直接通过 IIO 设备节点就能调频率、改带宽免去手写寄存器的麻烦。但这要求 Linux 内核和设备树都配好对新手来说门槛高。所以我给这套板子的建议是STM32 负责上电即配ZYNQ 通过串口或 AXI 寄存器向 STM32 下发频率切换命令两边一主一辅配合得很顺。2.2 PL 端 LVDS 数据通路和 DDC/DUC 处理AD9361 与 ZYNQ 之间有几种数据接口模式CMOS 并行、LVDS 差分、单端/双沿采样等。默认最常用的是 LVDS 模式数据线 P0~P7 加上 DCLK、FB_CLK、RX_FRAME 等信号时钟速率在几十 MHz 到上百 MHz 之间。这个速率用 ZYNQ 的普通 IO 引脚就能收但时序约束必须做对否则数据偶发错位极难排查。在 PL 端接收通路的核心逻辑通常是这样的LVDS 接收模块把差分数据转成并行 IQ然后经过一个同步模块对齐帧头接着进入 DDC 链路做数字下变频和抽取滤波最后通过 AXI4-Stream 接口把数据送入 DDR3 或 PS 侧。发送通路反过来DAC 的数据从 AXI 总线进来经过 DUC 上变频和插值滤波再通过 LVDS 送给 AD9361。这套流程看着复杂但资料包里的示例工程一般都已经封装好了。我的建议是自己不要从头造轮子先用厂商提供的 IP 核和示例代码跑通整个数据环再用 ILA 抓内部信号观察 IQ 数据的格式最后才考虑替换或修改滤波算法。2.3 STM32 做参数下发和状态监控的实践STM32 在这套板子里承担的任务有点像整机的“管家”。除了配置 AD9361它还负责读取功放温度、电源电压、驻波比等状态再通过串口或并行总线把这些信息汇报给 ZYNQ。反过来用户想切换频点、改变增益模式时ZYNQ 只需要发一条简单指令STM32 负责翻译成具体的 AD9361 寄存器写入操作。实际编码时我建议给 STM32 和 ZYNQ 之间定义一套简单明了的通信协议。比如使用固定的帧头、长度、命令字、校验位命令字包括SET_FREQ、SET_GAIN、GET_STATUS等。不要一来就上复杂的消息队列或远程调用框架先把能跑通的裸机代码做出来再逐步优化。3. 资料包里那堆源码和原理图按这个顺序吃才不亏3.1 先读原理图的时钟树和电源树拿到资料包有不少人急着打开 Vivado 工程跑综合结果综合到一半报时序错误完全不知道哪里的问题。我的习惯是先看原理图而且重点只看两页时钟树和电源树。AD9361 和 ZYNQ 都需要多路时钟。ZYNQ 的 PS 侧时钟来自板载 33.333MHz 晶振PL 侧可能需要独立的参考时钟AD9361 需要 40MHz 或类似频率的参考时钟作为内部 PLL 的基准。看时钟树至少能搞清楚这几个关键问题各路时钟源头在哪、都用什么电平标准、有没有经过时钟缓冲器或可编程晶振。这些直接决定了你在工程里选什么时种约束、PLL 怎么配置。电源树同样重要。ZYNQ 需要多路供电VCCINT、VCCAUX、VCCBRAM、VCCO 分别给不同 bank 的 IO 供电AD9361 的供电轨包括 VDD_DIG、VDD_ANA、VDD_TX 等。最常见的问题就是某个 bank 的 VCCO 电压接错导致 LVDS 电平不匹配信号完全不通。看电源树时重点确认每个 bank 的电压和原理图标注是否一致。3.2 源码工程的三个关键入口约束、IP 核、测试用例打开 FPGA 工程后不要从头把每个 RTL 文件都读一遍那是读不完的。我建议从三个入口切入。第一个入口是 XDC 约束文件。XDC 里定义了所有引脚的物理位置、IO 标准、时钟周期约束。读完约束你就能知道哪个引脚连到了 AD9361 的哪个数据线哪个时钟是主时钟哪些信号是异步跨时钟域的。这个信息比看原理图还直接因为原理图管脚太多容易看花眼。第二个入口是 IP 核列表。ZYNQ 工程里几乎一定会用到 ZYNQ7 Processing System IP、AXI DMA、Clocking Wizard可能还有 MIG DDR3 控制器。看看这些 IP 核的配置信息就能理解 PL 端整体数据流向。尤其是 AXI DMA 的配置突发长度、数据宽度、地址位宽都直接决定了大吞吐量场景下的性能。第三个入口是仿真测试用例。如果资料包里有 Testbench优先跑一下仿真。仿真看不到射频实际信号但能验证 AD9361 的时序模型、AXI 接口读写是否正确。我见过不少同学一上来就上板调时序问题却出在代码逻辑本身仿真一跑就现原形省大量时间。3.3 附送的 FPGA 数字图像处理资料怎么穿插着看资料包里附送图像处理资料很多人觉得和 SDR 没关系就丢在一边。实际上这恰恰是理解 ZYNQ 最好的补充材料。SDR 收发的 IQ 数据和图像传感器的像素数据在数字信号处理层面有大量相似之处。图像处理里常用的行缓存、卷积滤波、直方图均衡、DMA 搬运在通信信号处理里对应的是滑动窗滤波、相关运算、信道估计、高速缓存。尤其是图像采集用到的 MIPI CSI-2 接口、Sensor 配置、帧同步逻辑和 AD9361 的 RX_FRAME 同步本质上是一回事。所以我建议把图像处理资料当作“平行练习题”。当你在 SDR 工程里卡住时先去看图像处理工程里怎么处理 AXI Stream 数据流、怎么做乒乓缓存、怎么用 VDMA 回显到 HDMI这些架构思想完全可以移植到 SDR 的数据链路上来。4. 三个高频玩法FM 接收、频谱仪、图像采集加速4.1 用 AD9361 做 FM 广播接收的最小通路最经典的入门实验是 FM 广播接收频段大概在 87.5~108MHz。虽然现在数字广播也不少但 FM 模拟广播的调制方式简单特别适合验证整套链路。具体实现流程是这样的先把 AD9361 的本振频率设到你要听的电台频率信道带宽设到 200kHz 左右接收模式选 IQ 模式AD9361 输出的基带 IQ 数据进入 ZYNQ PL经过低通滤波后送到 PS 侧。在 PS 侧如果是裸机程序可以直接用 Cortex-A9 做 FM 解调先算相位差分得到解调音频再通过 I2S 接口播放出去。提示AD9361 的增益控制默认是自动的但做 FM 接收时建议先固定到手动增益把 LNA 和 VGA 增益设到中间值再根据实际信号强度微调。否则自动增益在信号强弱切换时会带来明显的噪声调制。4.2 频谱仪模式的参数配置思路把板子变成一台简易频谱仪是第二个很有意思的实验。基本原理是对 AD9361 输出的 IQ 数据做 FFT再把幅度谱显示到屏幕上。但要注意AD9361 的瞬时带宽是有限的通常配置为 20MHz 以下。想扫描更宽的频段就需要步进式扫描每隔一定频点设置一次本振频率采集一小段数据做 FFT然后拼接所有频点的频谱结果。这里有两个坑要提醒一是每个频点切换后要留出 PLL 锁定时间一般要延时几百微秒再开始采集否则频谱会不准二是不同频点的增益平坦度可能不一致最好先做一次校准用已知功率的信号源标定增益曲线。我通常的做法是在 PS 侧跑一个小型频谱仪服务用 Python 或 C 程序通过串口/UDP 下发频点切换命令然后从 PL 端 DMA 读取 FFT 结果拼接后通过网口发到上位机显示。整个流程跑通了你对“SDR 平台怎么用软件定义功能”这件事会理解得非常透彻。4.3 从 MIPI 摄像头到 FPGA 图像处理的延伸如果你把图像处理资料里的 MIPI 摄像头采集工程跑通了再回头看 SDR 工程会有一种非常强的复用感。两者都起源于传感器产生的高速并行/串行数据流都要经过物理层接口、字节对齐、数据打包、DMA 传输。用 FPGA 接收 MIPI 摄像头数据时需要处理 Lane 对齐、通道匹配、帧同步信号解析这和接收 AD9361 的 LVDS 数据流几乎是一个套路。图像数据进 DDR3 缓存后做缩放、滤波、边缘检测和 IQ 数据进 DDR3 后做 FFT、滤波、解调也是同一套存储和调度逻辑。所以我的建议是做 SDR 的同时抽一个周末把图像处理工程完整跑一遍然后有意识地去对比两个工程的模块划分。这种跨场景对比带来的理解深度远大于重复调 SDR 代码。5. 移植验证阶段最容易踩的坑我替你踩了一遍5.1 时钟域和复位设计数据错位的源头SDR 工程里最常见的疑难杂症就是“数据偶尔不对复位一下又好了”。十有八九是跨时钟域和复位设计出了问题。AD9361 的 LVDS 时钟来自外部PL 内部逻辑使用的是自己 PLL 产生的时钟两个时钟之间必然存在相位偏移。处理 IQ 数据时必须先用 FIFO 或异步同步器把数据安全地跨到主时钟域。千万别为了省资源直接打两拍就算同步高速数据流的同步必须考虑帧对齐和位对齐。复位设计同样容易被忽视。SDR 系统里既有外部复位按钮又有 AD9361 的 SPI 配置完成信号还有 PLL Locked 信号。我建议所有模块使用统一的异步复位、同步释放电路并且把复位释放时序和 AD9361 配置完成时序关联起来保证 AD9361 数据有效时PL 端逻辑已经处于确定状态。5.2 LVDS 约束报错和电平标准选择热词里提到的“7 系 FPGA 的 bank501”、“1.8V LVDS 在设置 IO 属性时选哪个值”我在调这套板子时都遇到过。ZYNQ 的 IO Bank 分布在芯片四周每个 Bank 的 VCCO 电压不同。对于 HR BankHigh RangeVCCO 通常是 1.8V 或 2.5V对于 HP BankHigh PerformanceVCCO 通常是 1.8V 或 1.5V。AD9361 的数据接口如果没有电平转换芯片通常直接连到 HP Bank配置为 LVDS 时 XDC 里要写成set_property IOSTANDARD LVDS_25 [get_ports ad9361_data_p[*]] set_property IOSTANDARD LVDS_25 [get_ports ad9361_data_n[*]]但注意确认 bank 的 VCCO 到底是什么电压选择LVDS_25还是LVDS1.8V选错的话综合布线后可能直接报 DRC 错误或者上板完全不通。注意LVDS 是差分标准需要成对引脚满足差分对规则且外部要有 100 欧姆终端电阻。有些板子内部已经集成终端有些则要求你外接原理图里要注意区分。5.3 调试手段ILA、逻辑分析仪和串口打印移植过程中会遇到仿真正常、上板不正常的状况这时就需要高效的调试手段。PL 端首选 ILAIntegrated Logic Analyzer它把采集逻辑直接嵌入到 FPGA 内部可以实时抓取 AD9361 的 LVDS 数据、AXI Stream 信号、DMA 描述符状态。用 ILA 时建议触发条件设置得精准一点比如抓 RX_FRAME 上升沿、抓 DMA 中断信号不要盲目抓几百万个样本否则分析阶段会非常痛苦。PS 端调试比较灵活串口打印是最直接的。ZYNQ 在裸机下设置 UART 打印很轻松在 Linux 下直接访问/dev/ttyPS0也行。我习惯在关键状态机里加上标记打印比如 AD9361 配置完成、DMA 传输完成、FFT 处理完成等。把这些日志对应到 ILA 抓到的信号时间点上基本能定位大多数数据通路问题。5.4 常见问题速查表现象可能的根因排查方法AD9361 读寄存器全为 0xFFSPI 时序错误、片选信号极性不对用示波器抓 SPI 波形确认 CPOL/CPHAPL 端 IQ 数据全为 0AD9361 未配置完成、LVDS 时钟未接入在 ILA 中观察 DCLK 和 RX_FRAMEDMA 传输卡死描述符未正确配置、地址未对齐检查 AXI DMA 寄存器和中断状态综合报 module not found工程路径不一致、IP 核未生成重新生成所有 IP添加源文件路径频谱图出现镜像频率本振谐波、IQ 不平衡做 AD9361 正交校准检查模拟前端滤波器LVDS 电平不匹配Bank 电压选错、IOSTANDARD 填错核对原理图 VCCO修正 XDC这套板子的调试过程本质上就是在“射频前端—FPGA 逻辑—嵌入式软件”三层之间反复定位问题。我个人的体会是资料再多也只是起点真正把 AD9361 寄存器配置弄清楚、把 ZYNQ 的 AXI 通路跑顺、把 STM32 的控制链路打通之后这块板子才真正变成你自己的平台。后续做自定义调制方式、接外部射频前端、甚至把开源网卡工程移植过来做高速数据通路都是顺理成章的事。本文还有配套的精品资源点击获取