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

扫频信号的时频特性与测试实践

扫频信号是一种频率随时间变化的测试信号,常用于系统辨识和频响分析。文章先说明线性扫频与对数扫频的差异,再用 MATLAB 示例解释扫频信号的生成与扫描率计算。结合 FPGA/C++ 实测,分析了方波扫频在 FFT 中出现的阶梯状频谱和谐波叠加,也解释了正弦扫频在全段 FFT 里出现纹波、厚度以及边缘效应的原因。结论是,扫频适合一次性观察整个频带的幅频特性,但要小心窗函数、截断和采样边界带来的假象。

GopherDev发布于 2026/6/30更新于 2026/7/2412 浏览
扫频信号的时频特性与测试实践

引言

扫频信号(Chirp)可以理解成一把会'移动刻度'的频率尺。它不是盯着一个固定频点重复激励,而是在一段时间里按既定规律把频率扫过去。做 AD 芯片、前端链路或者滤波器测试时,这种信号比单点正弦波更顺手,能把一段频带里的问题一次看出来。

1. 什么是扫频信号

文章配图

扫频信号(Sweep Signal),又称 Chirp 信号,特点很直接:频率会随着时间变化。上扫频是从低到高,下扫频则相反。

如果从听感上找类比,它有点像警报声、雷达声或者鸟鸣,音调一直在滑,不会停在某个音高上。

下面这段 MATLAB 代码生成了一个线性扫频信号,并画出时域和频域图。代码不长,关键是把'频率线性变化'这件事写对。

%% 扫频信号生成与分析脚本 % 功能:生成线性扫频信号,并绘制时域波形和频域频谱 
cclc; 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]); 
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('扫频信号特性分析');

这段脚本里,1 秒内频率从 10Hz 线性爬到 200Hz。中间时刻大约是 105Hz,结束时回到 200Hz。它表达的是'频率扫过一个区间',不是某个频点持续整段时间。

2. 扫描率和频率变化

扫描率就是频率变化的快慢: $$\text{Sweep Rate} = \frac{f_{end} - f_{start}}{T}$$

对这个例子来说,1 秒内从 10Hz 扫到 200Hz,平均每秒增加 190Hz。采样实现时,频率是按离散采样点更新的,但分析上可以直接按这个线性关系理解。

几个参数单独拎出来看更清楚:

  • 起始时刻 $t=0s$ 时,频率是 $10Hz$
  • 信号持续时间 $T=1.0s$
  • 终止频率 $f_{end}=200Hz$
  • 起始频率 $f_{start}=10Hz$
  • 3. 常见分类

    扫频一般分两类。

    线性扫频(Linear Sweep)

    频率按固定速率变化,结构最简单,做频响测试很常见。雷达脉冲压缩也会用这个思路。

    对数扫频(Logarithmic Sweep)

    频率按倍数变化,比如 10Hz、100Hz、1000Hz 这样往上走。音频测试里更常见,因为人耳对频率的感知不是线性的。

    4. 它和普通正弦波的区别

    信号类型频率特征波形外观
    普通正弦波恒定波峰间距始终一致
    扫频信号变化前段低频稀疏,后段高频密集

    正弦波像一根定尺,扫频更像滑尺,刻度一直在变。

    5. 为什么工程里喜欢用它

    扫频真正有价值的地方,是一次能把一整段频带摸清楚。做系统辨识、频率响应测试时,它比单点打频率省得多。

    拿 ADC 前端滤波特性举例:如果用单点正弦波测,就得一个频点一个频点慢慢扫,效率低,漏点也很常见。扫频的做法更直接,输入一个频带范围,采集后做 FFT,就能看出哪些频段被压下去,哪些频段还能正常通过。

    这时候看到的幅频曲线,实际上就是系统对不同频率的'态度'。

    6. 结合 FPGA / C++ 的实际测试

    文章配图

    项目里主要有两种模式:

    • Mode = 4:方波线性扫频,10Hz ~ 1MHz
    • Mode = 5:正弦波线性扫频,DDS 产生,10Hz ~ 1MHz

    关键公式也很直接:

    $dF_{per_second} = (F_{end} - F_0) / T_{sweep}$

    这里的 $dF$ 是 chirp rate,表示每秒频率增加多少;$F_0$ 是起始频率,$F_{end}$ 是终止频率。

    6.1 方波线性扫频(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 后,图上会出现比较明显的阶梯感。这个现象不奇怪,方波本来就带着奇次谐波,扫频后这些谐波也会一起往上跑,所以频谱上会看到多个宽带区域叠在一起。

    文章配图 文章配图 文章配图

    通道二是竖直放大后的结果。低频段能量更厚实,高频段慢慢变薄,这符合方波谐波衰减后的表现。

    图里 90kHz 到 125kHz 一段出现了突增,原因不是扫频规律变了,而是这段数据在原始序列里重复记录过两次,FFT 里就把这部分能量再叠了一次。对应的短时傅里叶结果也能看出这个重复痕迹:

    文章配图

    把 3 秒后的数据单独拿出来后,图形就正常了:

    文章配图

    6.2 正弦波线性扫频(100Hz ~ 2MHz)

    信号源输出的是一个 10 秒周期的正弦扫频,起始频率 100Hz,终止频率 2MHz。拍图时漏了 2MHz 那张,只能先用这张顶上:

    文章配图

    取完整一个周期后,采集波形的时域图、FFT 图和 STFT 图如下:

    文章配图 文章配图 文章配图 文章配图

    从 STFT 看,这个结果是对的,一条斜线很清楚。真正需要解释的是 FFT:为什么高频段看起来更厚,一个频率附近像是有两个值。

    放大后更明显:

    文章配图

    这类现象在有限时长的线性扫频里很常见。全段 FFT 不是在看'某个瞬时频率',而是在把整段信号的频率内容压到一张图上,所以会出现类似纹波的起伏。窗口截断、相位漂移、频谱泄露,都会让顶部看起来不是一条光滑直线。

    我当时试过直接给整段数据乘 Blackman 窗,结果并不好。扫频信号的频率和时间是一一对应的,你把整段信号两头压低,实际上是在把低频和高频一起削掉,FFT 看见的更像窗函数本身,而不是原始扫频特征。

    只做平滑处理会好一些,但也会把'高频更强'这种直觉打乱。这个时候更合理的看法不是盯着某个局部峰值,而是看整个频带是不是平、在哪个位置开始掉下去。

    如果图里在 1.8MHz 左右开始明显回落,通常说明链路已经接近带宽边界。反过来,如果 100Hz 到 1.5MHz 之间都很平,至少说明信号源和采集链路的幅频响应还算稳定。

    6.3 调整 STFT 显示

    背景发黄主要是色阶映射的问题,不是数据异常。把 clim 锁住,图会干净不少:

    文章配图 文章配图 文章配图

    % 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); % 手动锁色阶
    

    处理后的结果如下:

    文章配图

    7. 小结

    扫频信号的作用很简单:把一段频带按时间铺开,让系统在每个频率点上的反应都露出来。它适合做频响测试、系统辨识,也适合排查 ADC 前端这类链路里'哪段频率开始不对劲'。真正要留心的是扫频方式、采样率、窗函数和截断效应,这几个地方处理不好,图会很花,但结论未必靠谱。

    目录

    1. 引言
    2. 1. 什么是扫频信号
    3. 2. 扫描率和频率变化
    4. 3. 常见分类
    5. 线性扫频(Linear Sweep)
    6. 对数扫频(Logarithmic Sweep)
    7. 4. 它和普通正弦波的区别
    8. 5. 为什么工程里喜欢用它
    9. 6. 结合 FPGA / C++ 的实际测试
    10. 6.1 方波线性扫频(100Hz ~ 125kHz)
    11. 6.2 正弦波线性扫频(100Hz ~ 2MHz)
    12. 6.3 调整 STFT 显示
    13. 7. 小结
    • 免费图片AI生成工具免费生成了解详情
    • Magick API 一键接入全球大模型注册送1000万token查看
    • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
    • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
    • 100+免费在线小游戏爽一把
    极客日志微信公众号二维码

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

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

    更多推荐文章

    查看全部
    • 联邦学习核心算法 FedAvg 原理及数据不均衡解决方案
    • 新版 IntelliJ IDEA 恢复右上角 Git 更新和提交按钮设置
    • Spring Boot 自动配置:原理、条件注解与手写 Starter
    • Flutter modular_core 鸿蒙适配:微服务化架构与依赖注入实践
    • LazyLLM 多 Agent 应用全流程实践:从源码部署到可视化 Web 调试的低代码方案
    • 基于 Dify 与 LangBot 实现飞书智能体对话机器人
    • OpenHarmony WebRTC 编译与适配指南
    • LangChain 消息处理:缓存、过滤、合并与流式输出实战
    • Vue3 主流 AI 代码助手安装与配置指南
    • 基于SSM的教师业绩管理系统设计与实现
    • ANSYS Fluent 2026 R1 新功能:AI 如何重塑汽车风阻优化流程
    • Generative Agents:交互式人类行为模拟研究
    • Rust 异步代码的测试与调试实践
    • MCP Document Converter:让 AI 助手支持 25 种文档格式转换
    • Rust 桌面 GUI 框架 2025 年横评与选型指南
    • WebRTC 在 Android 中的应用实战指南
    • 基于 SpringBoot 的网页时装购物系统设计与实现
    • 使用本地大模型 Llama3 进行数据分类标记
    • Spring AI 调用大模型的几种方案实践
    • 基于 Python Django 与 Flask 的在线食品安全信息平台设计

    相关免费在线工具

    • 加密/解密文本

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

    • Keycode 信息

      查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

    • Escape 与 Native 编解码

      JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

    • JavaScript / HTML 格式化

      使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

    • JavaScript 压缩与混淆

      Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

    • Gemini 图片去水印

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