ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于FPGA的电磁超声脉冲压缩检测系统:从原理到实战

基于FPGA的电磁超声脉冲压缩检测系统:从原理到实战 简介本资源是一套基于ZYNQ-7020 FPGA平台的电磁超声脉冲压缩测厚系统课程设计实现方案面向嵌入式系统、无损检测与信号处理方向的高年级本科生及工程实践者旨在解决电磁超声因换能效率低导致回波微弱仅数十微伏、信噪比差、测厚精度受限的核心问题。资源包共349个文件涵盖VHDL/Verilog逻辑代码20个.v、15个.vhd、约束与脚本文件8个.xdc、22个.tcl、8个.bat、综合与仿真报告27个.log、12个.rpt、16个.rst、以及可直接烧录的bit配置文件和C语言驱动代码9个.c/9个.h整体大小为66.21MB。已有395人学习下载。用户可获得完整软硬协同设计流程从Chirp编码激励生成、回波接收与数字下变频到匹配滤波脉冲压缩算法FPGA实现再到ZYNQ PS端数据解析与厚度计算含可运行工程、关键模块注释、调试日志及实测验证说明具备强复现性与教学参考价值。 前阵子接手了一个编号为100010359的项目标题很直白基于FPGA的电磁超声脉冲压缩检测系统。当年在实验室里捣鼓过好一阵电磁超声也写过不少FPGA信号处理的代码看到这个题目第一反应就是这活儿有得聊。电磁超声换能器EMAT这东西有意思它不需要耦合剂可以隔着氧化层和粗糙表面检测金属内部缺陷在高温在线检测场景里几乎是不可替代的。但它有个硬伤换能效率低接收到的回波信号极其微弱往往被噪声淹得干干净净。所以得把雷达通信里那套脉冲压缩技术搬过来在FPGA里做编码激励、高速采集、匹配滤波硬生生把信噪比拉起来。这篇文章就围绕这个系统展开从原理、架构到具体的FPGA实现细节再到调试现场踩过的坑尽量讲透。适合三拨人看一是做无损检测或超声仪器开发的工程师想了解怎么用FPGA做信号处理二是专攻FPGA的开发者想看高速采集、DDS、FFT这些IP核怎么组合到一个实际项目里三是刚入门的研究生想把脉冲压缩和电磁超声这两个关键词串成一套能复现的方案。我尽量少整虚的聊点能直接上手的经验。1. 项目整体设计与思路拆解1.1 为什么是FPGA而不是DSP或ARM先说原理。电磁超声检测的核心是激励线圈在试件表面激发洛伦兹力或磁致伸缩效应产生超声波超声波在材料内部遇到缺陷后反射回来被接收线圈感应。整个过程不需要耦合剂探头与试件之间隔着空气间隙也能工作这对高温、粗糙、移动的工件非常友好。但也正因非接触能量转换效率很低回波信号通常只有微伏到毫伏级别而且周围全是电磁干扰。脉冲压缩是一种变戏法一样的技术发射端不发出一个短促的脉冲而是发出一段持续时间较长、频率或相位有特定变化的编码信号接收端用一个匹配滤波器处理回波把这段宽信号压缩成一个尖锐的窄脉冲。它的数学本质是发射信号的自相关函数如果是线性调频信号压缩输出就是sinc函数主瓣宽度约等于带宽的倒数。好处显而易见时宽T决定了发射能量能穿透更深带宽B决定了距离分辨率能把缺陷看得更细。时宽和带宽可以独立选取乘积D B×T称为压缩比脉冲压缩能把信噪比提升大约10×log10(D)分贝。那为什么非用FPGA呢我当年也纠结过用DSP处理回波后来发现三个理由让我彻底倒向FPGA。第一这个系统需要同时控制发射端的编码波形生成和接收端的高速采样FPGA的IO资源可以非常灵活地对接DAC、ADC以及各种功率放大器和滤波器控制引脚时序完全掌控在一个芯片里。第二脉冲压缩本质上是大量并行乘累加运算FPGA的DSP slice天然适合干这个而且延迟可以做到微秒级DSP串行执行指令数据搬运那一套在实时性上差了一截。第三无检测系统的参数中心频率、编码时宽、带宽、重复频率经常要改FPGA里用寄存器配置就能灵活切换不用重新制板子。1.2 系统架构与信号链设计这个项目的总体信号链可以分成两条路发射链路和接收链路都围绕FPGA这颗核心展开。发射链路是这样的FPGA内部产生一段数字编码波形我这里用的是线性调频LFM信号经过高速DAC转换成模拟信号再经功率放大器放大到几十伏甚至上百伏的激励脉冲去推动EMAT探头。接收链路则是EMAT探头接收到微弱的超声回波先经过低噪声放大器LNA进行初步放大再经过带通滤波器和AGC/VGA自动增益控制最后由高速ADC采样成数字信号送回FPGA。回FPGA后做数字下变频、抽取滤波、脉冲压缩匹配滤波之后提取缺陷回波的位置和幅度通过PCIe总线上传给上位机显示。这里必须强调一个环节发射和接收的同步。电磁超声检测大多数采用单探头自发自收模式也就是探头发射完激励信号之后马上切换到接收状态。这个过程需要一个极低延迟的收发切换控制信号而FPGA的引脚输出延迟是纳秒级的天然满足要求。系统时钟则由一个晶振或换能器源引出保证DAC、ADC、FPGA内部逻辑都跑在同一时间基准上。如果时钟不统一脉冲压缩后回波峰值位置会漂移测出来的声程就有误差。1.3 关键指标与参数权衡做系统设计时不能上来就写代码得先把几个关键参数定下来。这个项目目标是在钢件中检测埋深大约5mm到100mm范围内的缺陷钢中纵波声速约5900m/s横波声速约3200m/s。如果用纵波检测为了分辨1mm左右的缺陷需要的信号带宽大约是B c/(2Δd) 5900/(2×1) ≈ 3MHz。考虑实际滤波余量中心频率选在5MHz左右带宽取4MHz比较合理。时宽T的选择要权衡两个方向时宽越大发射能量越高SNR提升越明显但盲区也越大因为激励信号还没发完近表面回波就已经回来了。我这个项目里盲区控制在30us以内所以时宽选了50us这样压缩比D 4MHz × 50us 200理论信噪比增益约10×log10(200) ≈ 23dB已经足够让微伏级回波露出水面。编码形式也不是随便选的。常见的有线性调频LFM、Barker码、Costas跳频码等。我列个表格对比一下当时的考虑编码类型实现复杂度压缩比多普勒敏感性适用场景线性调频LFM低DDS即可大可灵活调节敏感频移导致失配静态/低速检测最常用Barker码极低相移键控小最长13位不敏感浅层高分辨率检测压缩比受限Costas跳频中大较敏感抗干扰/复杂环境但FPGA实现较繁琐对于一般的无损检测LFM基本是首选。它生成简单压缩比容易做大匹配滤波实现也成熟唯一的麻烦是匹配滤波输出旁瓣较高需要加窗函数压制。这个后面细说。2. 核心细节解析与实操要点2.1 编码激励与DDS生成FPGA里生成线性调频信号我推荐两种方式直接做一个相位累加器或者把波形采样点存进ROM再顺序读出。前者灵活后者简单。先讲简单可靠的ROM方案。先用MATLAB按公式s(t) A·exp(jπkt²)其中k B/T生成一个复数或实数的LFM波形量化为14位写入coe文件再在FPGA里用Block ROM存储。发射时用一个计数器从0读到N-1把数据送给DAC。这种方式的好处是波形完全可控不依赖DDS IP核也方便在ROM里叠加调制信息。缺点是需要存储资源如果时宽特别长、采样率特别高ROM容量会吃紧。但这个项目50us50MSPS才2500个点一个18k BRAM就放下了。如果用DDS IP核实时生成需要注意频率控制字的动态变化。Xilinx的DDS Compiler支持相位增量可编程我可以每隔几个时钟周期更新一次频率控制字让它按斜率线性增长。频率控制字的计算公式是K(t) f(t) × 2^N / f_CLK其中N是相位累加器位宽f(t) f_0 k·tk B/T是调频斜率。举个例子系统时钟100MHz相位累加器32位起始频率3MHz终止频率7MHz调频斜率为4MHz/50us 8×10^10 Hz/s那每个时钟周期频率控制字增量就是 ΔK k × 2^32 / (100MHz × 100MHz) ≈ 3435。看上去数值不大但要注意累加精度可能会让频率误差累积最好定期用计数器重置相位或者直接用ROM方案避免这个坑。我用的是ROM方案代码如下示意// 读取LFM波形的简单状态机 reg [11:0] addr_cnt; reg [13:0] lfm_data; always (posedge clk) begin if (trig_gen) begin addr_cnt 0; pulse_active 1b1; end else if (pulse_active) begin if (addr_cnt PULSE_LEN-1) begin addr_cnt 0; pulse_active 1b0; end else begin addr_cnt addr_cnt 1b1; end end end ROM lfm_rom_inst ( .clka(clk), .addra(addr_cnt), .douta(lfm_data) );注意DAC的时钟和FPGA逻辑时钟最好同一个源否则发射波形会出现相位跳变。另外激励信号经过功率放大器后功放的非线性会产生谐波影响接收端匹配滤波效果所以功放输出后要串一个带通滤波器。2.2 接收链路与高速ADC接口要点ADC选型也是绕不开的一步。这个项目用100MSPS、14位并行LVDS输出的高速ADC接口在FPGA端要特别注意。Xilinx FPGA的LVDS引脚可以直接接收差分信号但多路LVDS数据在布线时会有skew必须用ISERDES和bitslip做数据对齐。我建议在编写数据采集逻辑之前先用Xilinx的IBERT核或各厂商自带的串行链路测试工具把物理层验证一遍。IBERT可以运行PRBS伪随机码测试通过观察误码率和眼图快速判断PCB走线、连接器、电平标准是否正常。这个步骤千万不能省我之前有一次直接扎进数据处理逻辑跑完才发现ADC数据偶发错位排查半天原来是FPGA Bank电压配错了。先用IBERT测一遍模拟链路能省一周的调试时间。如果ADC接口是JESD204B那就更值得专门说两句。JESD204B是高速串行接口依赖REFCLK和SYSREF实现确定性延迟链路建立过程包括代码组同步、初始通道对齐、数据配置三个阶段。调试时最容易失败的是SYSREF时序不对导致subclass 1模式下的延迟不定。如果链路建立失败优先检查SYSREF相对REFCLK的建立保持时间可以用逻辑分析仪或ILA抓一下。实在不行把确定性延迟模式切换到subclass 0牺牲一点延迟确定性先把系统跑通。ADC采回来的数据直接做脉冲压缩也可以但中频采样会引入不必要的运算量最好先在FPGA里做一个数字下变频DDC。简单做法用本地NCO产生正交本振信号与ADC数据相乘得到I/Q两路基带信号然后通过CIC抽取滤波器把采样率降下来。CIC滤波器适合大抽取率结构里都是加法器资源占用少但它的通带会有滚降需要在后面接一个FIR补偿滤波器。Xilinx的CIC Compiler IP和FIR Compiler IP可以配合使用配置时注意抽取因子和输入位数防止溢出。2.3 脉冲压缩匹配滤波的FPGA实现这是整个系统的心脏。匹配滤波的数学表达是将接收信号与发射信号的共轭时间反转做卷积。在FPGA里有两种实现路径时域相关法。如果发射编码序列不长比如Barker码或者是固定的参考波形可以用一个滑动相关的结构用乘法器阵列把接收信号与参考序列做点积。复杂度是O(N×M)其中M是参考长度。对于LFM这类长编码序列M可能有几千甚至上万乘法器资源不够用不太现实。频域FFT法。这是更主流的选择。把接收信号分成固定长度的帧对每一帧做FFT乘以参考信号的FFT共轭预先计算好存放在ROM或DDR里再做IFFT得到的就是压缩后的时域信号。复杂度是O(N logN)而且Xilinx有现成的FFT IP核可配置为流水线或突发架构。缺点是延迟较大需要管理好数据帧的连续性。对于实时检测我采用50%重叠保留法每次读取一帧数据处理完再读取下一帧避免帧边界处信号被截断导致压缩结果错乱。具体到资源规划FFT点数要根据采样率和帧长度确定。我选择65536点对应50MSPS采样率下约1.31ms的时间窗口可覆盖深度约3.8m的钢中纵波声程完全够用。FFT IP核配置成定点或块浮点输入输出均设为复数参考信号FFT数据提前用MATLAB计算并量化存在BRAM或DDR里。IFFT输出要取幅值可以用CORDIC核计算复数模值然后把峰值位置和幅度通过AXI总线传给上位机。需要留意缩放策略。定点FFT IP如果不正确处理缩放容易溢出或者动态范围不够。我习惯在FFT IP里配置Block Floating Point模式它会自动调整所有蝶形级间的缩放因子最后输出一个公共指数。对IFFT也要同样处理两个缩放因子相乘要在一个长时钟周期内调整回来否则幅值会有数量级偏差。调试时可以先用MATLAB导出一组数据在Vivado仿真里跑一遍再和MATLAB结果对比误差在几个LSB以内就算达标。2.4 同步与存储同步是电磁超声系统里最容易被忽视的环节。我建议用FPGA内部的一个主状态机统一管理所有时序它产生一个激励触发信号同时产生一个采样使能信号两者之间的延迟通过参数配置。在实际的硬件上激励信号到功放再到EMAT再到回波回到ADC有一个固定的电器延迟和声程延迟这个值需要在标定阶段测量出来然后在算法里扣除。数据存储方面100MSPS、16位采样率实际上产生1.6Gbps的数据流。如果要把原始波下传PCIe或万兆以太网是必要的。但如果只做实时检测可以不用存全量原始数据而是存压缩后的A扫数据和少量特征值这样存储和传输压力小得多。我当时在板上加了一片DDR3利用MIG IP核做了AXI4接口的数据缓存原始波形只保留最近几次触发的结果压缩后的波形和峰值列表则批量上传。DDR3的读写带宽足够支撑这个数据量但需要注意AXI总线调度避免不同主设备比如PCIe DMA、FFT输出、CPU配置端口之间的带宽竞争导致死锁。3. 实操过程与核心环节实现3.1 硬件平台搭建与模块划分先说硬件选型。FPGA我选的是Xilinx Artix-7系列比如XC7A200T理由很直白资源够用集成的高速收发器数量不多但足够跑PCIe或千兆以太网关键是性价比高。如果你做的是更大规模的多通道系统可以考虑Kintex-7甚至Zynq UltraScale但单通道验证阶段用Artix-7足够了。板级模块大致划分如下模块核心器件功能接口FPGA核心板Artix-7 XC7A200T信号生成、采集、处理FMC、PCIe、以太网、LED发射DAC模块14bit 200MSPS DACLFM波形数模转换LVDS/并行CMOS功率放大模块线性功放/脉冲变压器激励信号高功率放大SMAEMAT探头磁体线圈组成电声换能专用连接器接收前端LNA、带通滤波、VGA回波调理SMAADC模块14bit 100MSPS ADC回波数字化LVDS电源与时钟DC-DC、PLL、晶振供配电、时基分配板级做PCB布局时一定要把FPGA核心板和模拟前端模块分离开至少用金属屏蔽罩隔离。EMAT激励瞬间会产生强磁场和电流冲击如果模拟前端地线处理不好回波通道会饱和甚至烧芯片。我踩过一次很大的坑就是功放和接收天线共用同一个电源地导致每次发射都被地弹打断。后来改成光耦隔离触发信号功放供电单独用一个大电流线性电源接收前端用电池供电问题立即消失。3.2 Vivado工程搭建与IP配置要点软件工程搭建我按以下顺序操作每一步都有验证点。第一步新建Vivado工程选对FPGA型号导入引脚约束XDC文件。高速ADC和DAC的引脚约束要特别留意差分对的正负极性、IO标准LVDS_25或LVDS_33、端接电阻DIFF_TERM、以及同名信号是否布在同一个Bank。建议使用Vivado里的IO Planning功能图形化检查。第二步创建时钟和复位模块。用Clocking Wizard生成系统时钟、DAC采样时钟、ADC采样时钟和DDR3参考时钟所有时钟必须保证同源且相位对齐。复位最好用Xilinx的Processor System Reset或自定义的同步复位发生器避免在高速电路里使用异步复位。第三步添加IP核。我们的IP清单包括DDS Compiler或者用ROM实现LFM我最终用ROMSelectIO接口IP读取ADC并行LVDS数据CIC Compiler做抽取滤波FIR Compiler做补偿滤波FFT IP做512点/4096点/65536点的FFT/IFFTCORDIC IP做复数模值MIG IP做DDR3控制器如果走PCIe还需要XDMA IP。配置FFT IP时我记得最关键的几个参数变换长度设为65536I/O数据宽度根据ADC量化为16位架构选Pipelined Streaming以获得低延迟缩放策略选Block Floating Point输出排序选Natural Order。这些参数决定了后续乘法器需要额外处理的缩放因子。第四步写顶层模块把所有IP连接起来。我的做法是把代码分成若干独立源代码文件发射波形生成模块、ADC采集对齐模块、DDC滤波模块、FFT脉冲压缩模块、峰值检测模块、上位机通信模块。每个模块都有独立的AXI-Lite寄存器接口用条件编译或通用寄存器来控制模式。第五步做行为仿真。我会先用MATLAB生成一组带噪声的模拟回波导出成文本文件然后用testbench把这些数据喂给ADC采集模块观测整个流水线处理后的输出。仿真通过后再上板实测这样能把算法问题和硬件问题分开。3.3 参数标定与实测结果分析上板后第一步是标定。用一块已知厚度的碳钢试块厚度比如50mm把EMAT探头放上去采集一次完整的发射-回波过程压缩后会在对应声程处看到一个明显的峰值。用这个峰值位置换算零点延迟t_zero t_peak - 2d/c。然后把t_zero固化到寄存器里之后所有测厚结果都自动扣除这个值。实测过程中我用示波器在功放输出端正常看到激励脉冲在ADC输入端可以观察到微弱的回波如果不做脉冲压缩回波基本淹没在噪声中。压缩处理之后可以明显看到一个尖峰幅度比噪声高好几个数量级。用固定衰减器做定量测试发现压缩前后的信噪比提升约20dB与理论上23dB的增益接近说明匹配滤波器实现得比较理想。旁瓣处理也是重点。LFM信号直接做匹配滤波输出旁瓣相对主瓣约-13.2dB这个水平对于缺陷检测来说不够干净。我在生成参考信号时引入了Hamming窗函数来压制旁瓣实测旁瓣降到-35dB以下但主瓣宽度变宽了约1.5倍也就是距离分辨率略降。在实际的无损检测标准里这是可以接受的权衡。4. 常见问题与排查技巧实录4.1 高速串行接口不稳定数据错位我做这个系统时最头疼的就是ADC数据偶发错位。整体上看灵异得像中邪跑一段时间就出现几条竖线重启又好了。后来用IBERT核跑了PRBS7测试在200MSPS的眼图里发现信噪裕量不足问题定位到FPGA的LVDS Bank电压设置不对原本应该是1.8V被配置成2.5V。IO标准不仅决定逻辑电平还影响输入端的动态范围和噪声容限。这个问题在Xilinx的手册里其实写得很清楚LVDS使用VCCO必须匹配。检查完Bank配置后把IBERT眼图重新跑了一遍误码率降为0ADC数据一直稳定。类似的还有一个坑LVDS跨Bank布线导致skew。如果ADC的多路数据线跨越了不同Bank那么不同Bank内的输入延迟可能有差异导致bitslip对不齐。解决方法是尽量把所有数据线约束到同一个Bank或者在约束文件里使用set_input_delay做精细的相移补偿。4.2 脉冲压缩后旁瓣过高或波形畸变压缩输出旁瓣抬高通常有几个来源发射波形本身有相位噪声、功放饱和导致幅度失真、ADC输入信号过载、FFT缩放设置不当。排查顺序从源头开始先用示波器看功放输出确认LFM波形是否干净有没有削顶再调整VGA增益让ADC输入峰值维持在满量程的70%左右防止数字截位引入谐波。如果这些都正常问题多半在参考信号上。别忘了匹配滤波器使用的参考序列必须和发射信号完全一致包括同样的窗函数、同样的调频斜率。我最初在MATLAB里生成参考序列时没加窗实际发射时又对波形做了平滑导致失配旁瓣就抬高了。把MATLAB里的发射波形导出为coe文件直接作为参考信号源这个问题就消失。4.3 同步抖动与假回波每次触发后压缩峰值的延迟不断变化或者出现好几个看起来都像缺陷的尖峰。先检查触发信号是否干净是否与DAC时钟、ADC采样时钟对齐如果用的是外部触发源一定要在FPGA内部做一次同步把它倍频到系统时钟域否则触发时间抖动会直接变成声程误差。假回波往往来自反射和保护电路。功放激励结束后接收链路需要一小段恢复时间如果此时回波过来会被限幅电路或前端滤波器削弱形成与真实回波叠加的假峰。解决方法是加入T/R开关让发射高压信号不直接进入接收端同时设置接收链路的消隐时间在FPGA内部把激励后前几微秒的数据标记为无效。再说到噪声问题。有一次我把激励功率调大结果回波反而变差了原因是强激励在金属试件表面激发出多个模式电磁超声除了纵波还会有横波和表面波这些非目标模式会在脉冲压缩后形成伪峰。我通过增加带通滤波器带宽选择和时域门控只保留目标波型问题才解决。4.4 问题排查速查表整理一个速查表方便现场复现故障现象可能原因快速定位方法解决办法ADC数据错位/misalignedLVDS Bank电压错误、skewIBERT PRBS测试修正IO标准、使用bitslipJESD204B链路建立失败SYSREF时序不对ILA抓REFCLK/SYSREF调整SYSREF延迟或改subclass 0压缩输出旁瓣偏高参考信号与发射信号失配用发射波形作为参考统一波形源压缩峰值抖动触发信号未同步检查触发与采样时钟关系内部多级同步出现假回波T/R切换残留、多模式波改变频率/门控观察加T/R开关和消隐FFT输出幅值异常缩放因子未补偿用正弦信号自测统一定点缩放上位机数据乱码DDR带宽不足或DMA死锁检查AXI带宽优化数据调度最后再分享一个小经验整个系统跑通之后我始终没有完全放开所有优化而是保留了每个模块的原始数据输出开关比如可以导出ADC原始数据、DDC后数据、压缩后数据。这样每次现场出问题都可以用MATLAB或Python离线对比各级数据快速定位是哪一级出了问题。这种逐级留痕的习惯比任何高级调试技巧都管用。这套系统做完后我又把它扩展到了双通道收发模式FPGA里多例化一套脉冲压缩链路代码结构化之后其实没费太大劲。如果后续要做相控阵或者多探头阵列这套架构的基础打得牢扩展空间还是很可观的。对于新接手类似项目的人来说我的建议是先把MATLAB里的脉冲压缩算法完全跑通再往FPGA上搬不要一上来就调IP核。把信号处理的基本功打扎实FPGA只是把算法变成实物的一层皮真正难的永远是对物理和信号的理解。本文还有配套的精品资源点击获取
返回列表