跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
MATLAB / Octave算法

扫频信号(Chirp)原理、分类及工程应用测试

综述由AI生成扫频信号(Chirp)的原理、分类及工程应用。扫频信号频率随时间变化,分为线性和对数两种。主要用于系统辨识和频率响应测试,相比单点测试效率更高。文章提供了 MATLAB 生成代码及 FPGA/C++ 实现逻辑,分析了方波和正弦波扫频的实测结果,包括 FFT 频谱的阶梯状分布、菲涅耳纹波成因及窗函数对频谱的影响。通过 STFT 和 FFT 对比,揭示了采样率、相位敏感性及频谱泄露对测试结果的影响,为 ADC 前端电路测试提供理论参考。

雾岛听风发布于 2026/4/6更新于 2026/5/2228 浏览
扫频信号(Chirp)原理、分类及工程应用测试

什么是扫频信号?

定义: 扫频信号(Sweep Signal),又称为 Chirp 信号(线性调频信号)。它的核心特征是频率随时间有规律地变化。

听觉类比: 它的音调不是固定的,而是像警报声、雷达声或鸟鸣声一样,从低音平滑过渡到高音(上扫频),或者反之(下扫频)。

示例代码:

%% 扫频信号生成与分析脚本 % 功能:生成线性扫频信号,并绘制时域波形和频域频谱 clc; clear; close all; %% 1. 参数设置 fs = 2000; % 采样率 (Hz),设高一点以便观察频谱 T = 1.0; % 信号持续时间 (秒) f_start = 10; % 起始频率 10Hz f_end = 200; % 终止频率 200Hz %% 2. 信号生成 t = 0 : 1/fs : T - 1/fs; % 时间轴 % 线性扫频信号公式: % 瞬时频率 f(t) = f_start + k * t % 相位 phi(t) = 2 * pi * 积分(f(t)) = 2 * pi * (f_start * t + 0.5 * k * t^2) k = (f_end - f_start) / T; % 频率变化率 (Hz/s) phase = 2 * pi * (f_start * t + 0.5 * k * t.^2); %相位等于瞬时频率的积分 signal = sin(phase); % 生成正弦扫频信号 %% 3. 频域分析 (FFT) N = length(signal); % 采样点数 f = (0 : N-1) * (fs / N); % 频率轴 (0 到 fs) Y = fft(signal); % 快速傅里叶变换 P2 = abs(Y / N); % 双边频谱幅度 P1 = P2(1 : floor(N/2)+1); % 取单边频谱 P1(2:end-1) = 2 * P1(2:end-1); % 幅度修正 f_axis = f(1 : floor(N/2)+1); % 单边频率轴 %% 4. 绘图 figure('Color', 'w', 'Name', '扫频信号分析'); % --- 子图 1: 时域波形 --- subplot(2, 1, 1); plot(t, signal, 'b', 'LineWidth', 1); title(['时域波形 (Time Domain): ', num2str(f_start), 'Hz \rightarrow ', num2str(f_end), 'Hz']); xlabel('时间 (s)'); ylabel('幅度'); grid on; xlim([0, T]); % 局部放大提示(可选) text(0.1, 1.2, '\downarrow 低频疏松', 'Color', 'g', 'FontSize', 10); text(0.8, 1.2, '\downarrow 高频密集', 'Color', 'r', 'FontSize', 10); % --- 子图 2: 频域图 (FFT 频谱) --- subplot(2, 1, 2); plot(f_axis, P1, 'r', 'LineWidth', 1.5); title('频域图 (Frequency Domain / FFT Spectrum)'); xlabel('频率 (Hz)'); ylabel('幅度 (|P1(f)|)'); grid on; xlim([0, f_end + 50]); % X 轴范围显示到终止频率稍微多一点的地方 ylim([0, 1.2]); % 添加标注:展示频谱的平坦特性 rectangle('Position', [f_start, 0, f_end-f_start, 1], 'EdgeColor', 'k', 'LineStyle', '--'); text((f_start+f_end)/2, 0.5, '有效频带能量分布', 'HorizontalAlignment', 'center'); % 调整布局 sgtitle('扫频信号特性分析');

代码解释: 在这段 MATLAB 代码示例中,参数设定如下:

  • 采样率 fs = 2000 Hz
  • 持续时间 T = 1.0 秒
  • 起始频率 f_start = 10 Hz
  • 终止频率 f_end = 200 Hz

该信号在 1 秒钟的时间内,完成了一次从低频到高频的'滑行'。中间时刻 (t = 0.5s) 频率匀速增加到 105Hz。结束时刻 (t = 1.0s) 频率达到最终的 200Hz。

扫描率 (Sweep Rate) 计算

扫描率代表了频率随时间变化的'速度': $$\text{Sweep Rate} = \frac{f_{end} - f_{start}}{T}$$ 这意味着在这一秒钟里,每一毫秒,波形的频率都会增加。具体的时间变换还和代码里的时间精度有关系,也就是 1/fs,频率以这个时间精度来变化。

  • 起始时刻 ($t=0s$): 波形的振荡频率为 $10Hz$(每秒振动 10 次)。
  • 信号持续时间 ($T$): 1.0 秒
  • 终止频率 ($f_{end}$): $200Hz$
  • 起始频率 ($f_{start}$): $10Hz$

直观理解:与普通正弦波的区别

信号类型频率特征波形外观
普通正弦波恒定波峰与波峰之间的距离(周期)始终保持不变。
扫频信号变化起始段(低频):波形稀疏,波浪很宽,波峰间距大。
后段(高频):波形密集,波浪紧凑,波峰间距极小。

常见分类

根据频率变化的规律,主要分为两类:

  1. 线性扫频 (Linear Sweep)
    • 规律: 频率随时间匀速增加。
    • 应用: 通用的频响测试、雷达脉冲压缩。(注:本项目中使用的是此类)
  2. 对数扫频 (Logarithmic Sweep)
    • 规律: 频率随时间成倍增加。
    • 示例: 10Hz $\rightarrow$ 100Hz $\rightarrow$ 1000Hz...
    • 应用: 音频设备测试(因为人耳对频率的感知是非线性的,呈对数关系)。

核心作用:为什么要用扫频信号?

在工程中,生成扫频信号的主要目的是为了进行 系统辨识 (System Identification) 或 频率响应测试。

场景假设: 测试采集板(ADC 前端电路)的滤波特性。

  • ❌ 笨办法(单点测试):
    • 手动输入 100Hz 测幅度;手动输入 10Hz 测幅度... 重复无数次。
    • *缺点:效率极低,容易漏掉中间的频率点。
  • ✅ 聪明办法(扫频测试):
    • 原理: 这个信号在时域上虽然只是一段波形,但在频域上包含了该范围内的所有频率成分。
    • 结果分析: 将采集到的波形进行 FFT 分析。如果发现高频部分的幅度明显衰减,即可直接得出电路的'幅频特性曲线'(Bode 图)。
    • *优点:一次采集,全频段分析。

操作: 输入一个从 $F_{start}$ 到 $F_{end}$ 的扫频信号。

项目实战分析 (结合 FPGA/C++ 代码)

基于现有的 C++ 与 FPGA 代码逻辑,本项目中的应用如下:

  • 工作模式:
    • Mode = 4: 方波线性扫频(10Hz ~ 1MHz)。
    • Mode = 5: 正弦波线性扫频(DDS 产生,10Hz ~ 1MHz)。
  • 关键参数定义:

代码逻辑: $$dF_{per_second} = \frac{F_{end} - F_0}{T_{sweep}}$$

  • $dF$ (Chirp Rate): 频率变化率,即每秒钟频率增加多少 Hz。
  • $F_{end}$ (Stop Frequency): 信号终止频率 (e.g., 125kHz)。
  • $F_0$ (Start Frequency): 信号起始频率 (e.g., 100Hz)。

实际测试结果

测试信号:方波线性扫频(100Hz ~ 125kHz)
unsigned F0 = 100; //起始频率 
unsigned Fend = 125e3; //截至频率 
double dF_per_second = (Fend - F0) / 10; // Hz/s 从 100Hz 扫到 125kHz 需要 10 秒。 
unsigned dF = unsigned(dF_per_second / 1e3 * 65536); //调整率=dF*1kHz,dF 为 16-16 定点数 
dF_per_second 这个是总的时间, 
// 1/1e3 相当于每过 1/1e3 变换一次频率,对应每 1 毫秒 (1ms) 更新一次频率每毫秒的频率增量 = 12,490 / 1000 = 12.49 Hz 

对采集的信号做 FFT 的结果图如下: FFT Result FFT Result FFT Result

通道二是竖直放大后的结果。实验结果的频谱呈现出明显的阶梯状分布,这符合扫频方波的频谱:

谐波分量:你看到的后续几个较高的阶梯(分别在约 300kHz、500kHz 等位置起始)正是方波的奇次谐波(3 次、5 次谐波等)产生的扫频带。由于方波包含丰富的谐波,这些谐波也会随着基频一起扫频,从而在 FFT 上表现为多个宽带区域叠加。幅度衰减:随着频率升高,谐波能量自然下降,这解释了为什么高频段的'阶梯'高度越来越低。

宽带平台:因为频率是从 $100\text{Hz}$ 匀速扫描到 $125\text{kHz}$,在长达数秒的观测时间内,基频在这一范围内均匀分布,形成了一个低频端的'能量平台'。

至于为什么在 90khz 到 125khz 部分会有突增,是因为这段数据中 90khz 和 125khz 部分重复了两次,所以能量会更高一些。短时傅里叶波形如下图所示: STFT

频率重叠(Overlap):在时间轴约 $3\text{s}$ 的位置,你可以看到原本平稳上升的斜线突然出现了一个'断层'或'重叠区域'。

重复采集 = 能量加倍:如果你在数据序列中对 $90\text{kHz} \sim 125\text{kHz}$ 段进行了两次重复记录,那么在 FFT 计算时,这一频段的贡献时长增加了一倍。

取 3s 以后的数据: Data

这个图像就是正常的。

测试信号:正弦波线性扫频(100Hz ~ 2MHz)

通过信号源输出:起始频率为 100hz,终止频率是 2Mhz,扫频周期是 10s 的正弦波线性扫频信号。如下图所示: Signal Source

取一个完整的周期,对应的采集波形的时域图、FFT 图和 STFT 图: Waveform FFT STFT STFT Detail

从短时傅里叶变换来看,这个结果符合我们的预期。对于 FFT 的结果有点不太理解,高频部分能量高我可以理解,这是因为高频的周期短,相同时间内出现其波形出现的次数会更多。但是为什么一个频率下看起来会有两个值呢?放大 FFT 的图来看: FFT Zoom

FFT 图的幅值有点像正弦波变化,我们来看看技术解释:

这是一个非常精彩的观察!在处理线性扫频信号(Chirp Signal)时,FFT 结果呈现出这种'厚度'以及像正弦波一样的幅度振荡(通常被称为谱平坦度纹波或菲涅耳纹波),是信号处理中的经典现象。

你看到的'两个值'和'正弦波波动',可以通过以下三个核心物理原因来解释:

线性扫频的'菲涅耳纹波' (Fresnel Ripples) 当你对一个有限时长的线性扫频信号进行全段 FFT 时,其频谱并不是理想的矩形(虽然理想状态下能量应该是平坦的),而是受菲涅耳积分(Fresnel Integrals)支配。视觉上的'两个值':当你放大 FFT 图时,看到的像正弦波一样的起伏,实际上是频谱的包络振荡。那些'高点'和'低点'连接起来,就像是在频谱顶端画出了两条轨道,让你感觉一个频率有两个值。

采样率与奈奎斯特频率的边缘效应 你的采样率是,而终止频率设为。相位敏感性:在高频段,采样点落在正弦波的什么位置(是波峰还是过零点)对计算出的幅值影响极大。随着扫频的进行,信号相位与采样时钟之间的关系在不断漂移,这种'相位差'的周期性变化在 FFT 上就表现为了振荡的包络。

频谱泄露与窗口函数的相互作用 如果在计算 FFT 时没有使用合适的窗函数(如 Hamming 或 Blackman-Harris),信号的能量会从一个频率点'泄露'到相邻的频率点。相干干扰:扫频信号是一个宽带信号。在 FFT 的某一个频率单元(Bin)里,不仅包含该时刻的频率能量,还包含了相邻时刻频率泄露过来的能量。相消与相加:这些泄露的能量具有不同的相位。它们在某些频率点互相增强(波峰),在某些点互相抵消(波谷),从而形成了你看到的类似'正弦波'的起伏。

为什么 STFT(时频图)看起来不一样? 观察 STFT(短时傅里叶变换),你会发现它是一条清晰的斜线,没有这种剧烈的振荡。原因:STFT 是分段看频率,每一段内的频率几乎是恒定的。全段 FFT 的局限:全段 FFT 是把 10 秒内所有的频率能量'强行'压缩到一个平面上看。它反映的是信号的整体统计特性,而非瞬时特性。

如果你想验证这种波动是否源于'截断'和'相位',可以尝试以下操作:改变窗函数:在 MATLAB 计算 FFT 前,将 data1 乘以一个 blackman 窗。你会发现频谱顶部的纹波(即你看到的正弦波波动)会明显变小。

降低终止频率:将终止频率设为 $1\text{MHz}$(远低于奈奎斯特频率)。观察高频部分的能量是否还会有那种异常的抬升。

能量叠增的误区:你提到'高频周期短,出现次数多所以能量高',这在直觉上是对的,但在线性扫频中,信号在每个频率点停留的时间是严格相等的。你看到的后期能量升高,实际上很可能是因为频率接近 $fs/2$ 时,抗混叠滤波器的群延迟或者采样混叠带来的能量堆积。

临界点现象:$2\text{MHz}$ 恰好是你的奈奎斯特频率($fs/2$)。在这个点上,每个信号周期只有 2 个采样点。

波动来源:扫频信号在开始($100\text{Hz}$)和结束($2\text{MHz}$)处是突然开启和关闭的。这种时域的'截断'会导致频谱在频域内产生类似吉布斯现象的振荡。

对于加窗函数的结果:

加窗处理 (Windowing):消除扫频信号突然开始和结束带来的'截断效应'(菲涅耳纹波)。包络提取与平滑:消除由于采样相位漂移导致的细微震荡。

优化后的 FFT 绘图代码 将原脚本中的 Enable_FFT 部分替换为以下代码:

结果:

这个结果明显不对。扫频信号的特性:您的信号是线性扫频信号。这意味着时间与频率是严格一一对应的。物理效果:当您把这整个 10 秒长的信号乘以一个 Blackman 窗时,您实际上是手动压低了低频和高频的振幅,只保留了中间频率的强度。

结论:FFT 图形完全还原了 Blackman 窗的形状。您看到的不是频率响应,而是被你'亲手'压低后的信号包络。

只做平滑的效果:

这个看起来效果会好一些,但是把直接的高频部分能量大的结论打破了。结果解析如下:

观察 1.8MHz 后的下降:图中,结尾处幅度明显萎缩。在纯平滑的 FFT 图中,您会看到红线在 $1.8\text{MHz}$ 附近开始明显的'跳水',这反映了您硬件电路的截止频率。

如果红线非常平:说明您的信号源输出和 ADC 采集系统在 $100\text{Hz} \sim 1.5\text{MHz}$ 范围内具有极佳的幅频平坦度。

数据的后部 = 高频(约 $2\text{MHz}$) 数据的中部 = 中频(约 $1\text{MHz}$) 数据的前部 = 低频($100\text{Hz}$ 附近)

窗函数的形状:Blackman 窗(以及大多数窗函数)在时域上的形状是一个中间高、两头低的钟形曲线。它的起始点和终点的值几乎为 $0$,只有中间部分的值为 $1$。

在这里在保留几张图: Image Image Image

背景是黄色是因为 0 处使用的是黄色,改一下映射就好了。如下:

% STFT 参数 window_size = 8192; overlap = round(window_size * 0.5); nfft = 8192; % 颜色限制 (根据信号强度调整) C_Limit = [20 120]; figure('Name', ['时频轨迹分析 - ', name], 'Color', 'w'); % 绘制声谱图 spectrogram(data, window_size, overlap, nfft, fs, 'yaxis'); title(['时频轨迹 (Spectrogram) - ', name], 'Interpreter', 'none'); colormap('jet'); colorbar; % 调整显示范围 (根据实际情况调整) %ylim([0 0.2]); % 例如只看 0~200kHz (单位是 MHz 时) 或者根据 fs 调整 clim(C_Limit); % 手动锁色阶

结果如下: Result

总结

扫频信号本质上是一把'频率的尺子'。通过发送这把'尺子'穿过硬件系统,可以一次性测量出系统在各个频率刻度下的性能表现(如增益、衰减、相移等)。

目录

  1. 什么是扫频信号?
  2. 扫描率 (Sweep Rate) 计算
  3. 直观理解:与普通正弦波的区别
  4. 常见分类
  5. 核心作用:为什么要用扫频信号?
  6. 项目实战分析 (结合 FPGA/C++ 代码)
  7. 实际测试结果
  8. 测试信号:方波线性扫频(100Hz ~ 125kHz)
  9. 测试信号:正弦波线性扫频(100Hz ~ 2MHz)
  10. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Flutter 三方库 ethereum_addresses 的鸿蒙化适配指南
  • 多路双向串口转网口上位机 C++ 源码及 Socket 通信实现
  • Redis 压缩列表、Listpack 及哈希表扩容原理
  • cJSON 1.7.19 源码深度分析:数据结构、解析流程与注释实践
  • 机场出租车调度问题的数学建模与 Python 仿真实现
  • 使用 VibeThinker 解决动态规划典型题例
  • IntelliJ IDEA 编译报错:Java 源发行版与目标发行版不一致处理
  • 35 道常见前端 Vue 面试题详解
  • C++ 泛型编程与模板技术详解
  • 近五年体内微纳米机器人赋能肿瘤精准治疗综述:聚焦 GBM
  • Linux 线程管理与 POSIX 线程库实战
  • Chrome 扩展:一键转换网页图片格式为 PNG/JPG/WebP
  • C++26 CPU 亲和性底层机制与性能优化实践
  • 大模型算法工程师核心面试题及参考答案
  • 地图开发基础概念:服务类型、坐标系与 SDK 简介
  • 机器学习:聚类分析算法原理与分类
  • Clawith:开源多智能体协作平台
  • 数据结构:AVL 树的原理与实现
  • Python ETL 框架 Pathway 实时数据处理与 OpenBB 金融分析平台介绍
  • 数据结构:哈希表原理与冲突解决

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online