扫频信号 (Sweep/Chirp Signal) 原理与应用

扫频信号 (Sweep/Chirp Signal) 原理与应用

目录

前言

1. 什么是扫频信号?

2. 波形频率是如何变化的?

3. 扫描率 (Sweep Rate) 计算

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

3. 常见分类

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

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

实际测试结果:

测试信号:方波线性扫频(100Hz ~ 125kHz)

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

实验建议

优化后的 FFT 绘图代码

6. 总结


前言

        本文旨在记录扫频信号(Chirp)的时频特性,为后续基于扫频法的AD芯片性能测试与数据分析提供理论参考。

1. 什么是扫频信号?

定义:

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

听觉类比:

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

示例代码:

%% 扫频信号生成与分析脚本 % 功能:生成线性扫频信号,并绘制时域波形和频域频谱 % 作者:lhw % 日期:2026-01-16 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 代码示例中,参数设定如下:2. 波形频率是如何变化的?

这个信号在1秒钟的时间内,完成了一次从低频到高频的“滑行”:中间时刻 (t = 0.5s): 频率匀速增加到 105Hz结束时刻 (t = 1.0s): 频率达到最终的 200Hz。3. 扫描率 (Sweep Rate) 计算

扫描率代表了频率随时间变化的“速度”:



扫描率



这意味着在这一秒钟里,每一毫秒,波形的频率都会增加。具体的时间变换还和代码里的时间精度有关系,也就是1/fs,频率以这个时间精度来变化。

起始时刻 (

$t = 0s$

): 波形的振荡频率为

$10Hz$

(每秒振动10 次)。

信号持续时间 (

$T$

): 1.0 秒

终止频率 (

$f\_end$

):

$200Hz$

起始频率 (

$f\_start$

):

$10Hz$

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

信号类型频率特征波形外观
普通正弦波恒定波峰与波峰之间的距离(周期)始终保持不变。
扫频信号变化

起始段(低频):波形稀疏,波浪很宽,波峰间距大。

 

后段(高频):波形密集,波浪紧凑,波峰间距极小。


3. 常见分类

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

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

示例: 第1秒 10Hz

$\rightarrow$

第2秒 20Hz

$\rightarrow$

第3秒 30Hz...


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

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

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

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

操作: 输入一个从

$F_{start}$

$F_{end}$

的扫频信号。

手动输入 100Hz

$\rightarrow$

测幅度;

手动输入 10Hz

$\rightarrow$

测幅度;


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

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

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

代码逻辑:

dF_per_second = (Fend - F0) / 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的结果图如下:

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

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

宽带平台:因为频率是从

$100\text{Hz}$

匀速扫描到

$125\text{kHz}$

,在长达数秒的观测时间内,基频在这一范围内均匀分布,形成了一个低频端的“能量平台”。

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

AI解释:

        根据你提供的最新时频图以及对数据结构的补充说明,你对 FFT 结果中能量突增的解释非常合理且具有说服力

为什么你的解释是合理的?

在信号处理中,FFT 累积的是整个观测时间窗内的总能量。物理表现:这在频谱图上会直接表现为一个阶梯状的抬升,其抬升的幅度(功率)与重复的时间比例成正比。

短时傅里叶变换(STFT)轨迹分析

        观察你优化后的轨迹图,我们可以清晰地看到数据重复导致的特征:密集的亮线:在那一刻,多条频率轨迹同时出现(主扫频线和重复段的扫频线交织),这解释了为什么在那一时间点背景能量骤增。谐波干扰:由于是方波,图中除了主扫频线(最亮的那条),还有许多平行的斜线,那是方波的高次谐波同步扫频的结果。

频率重叠(Overlap):在时间轴约

$3\text{s}$

的位置,你可以看到原本平稳上升的斜线突然出现了一个“断层”或“重叠区域”。

重复采集 = 能量加倍:如果你在数据序列中对

$90\text{kHz} \sim 125\text{kHz}$

段进行了两次重复记录,那么在 FFT 计算时,这一频段的贡献时长增加了一倍。

取3s以后的数据:

        这个图像就是正常的。

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

        通过信号源输出:起始频率为100hz,终止频率是2Mhz,扫频周期是10s的正弦波线性扫频信号。如下图所示(拍图的时候忘记拍2Mhz的图了,先用着这张):

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

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

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

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

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

线性扫频的“菲涅耳纹波” (Fresnel Ripples)

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

采样率与奈奎斯特频率的边缘效应

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

频谱泄露与窗口函数的相互作用

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

为什么 STFT(时频图)看起来不一样?

        zhi如察 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$

        在这里在保留几张图:

        背景是黄色是因为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); % 手动锁色阶

结果如下:


6. 总结

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

Read more

N46Whisper:让日语视频字幕制作变得如此简单

N46Whisper:让日语视频字幕制作变得如此简单 【免费下载链接】N46WhisperWhisper based Japanese subtitle generator 项目地址: https://gitcode.com/gh_mirrors/n4/N46Whisper 还在为日语视频制作字幕而头疼吗?N46Whisper正是你一直在寻找的智能解决方案!这款基于云端AI技术的日语语音识别工具,彻底改变了传统字幕制作的繁琐流程,让每个人都能轻松上手。 为什么你需要这款工具 想象一下,原本需要数小时手动打字的工作,现在只需要几分钟就能完成。这就是N46Whisper带来的效率革命: * 零门槛使用:无需安装任何软件,打开浏览器就能开始工作 * AI精准识别:采用先进的Whisper技术,日语语音识别准确率惊人 * 云端极速处理:借助Google Colab的强大计算能力,处理速度超乎想象 * 双格式支持:ass和srt两种主流格式任你选择 快速入门:三步搞定日语字幕 第一步:准备环境 打开Google Colab,上传N46Whisper.ipynb文件,系

AIGC大模型系统化学习路径:从理论到工业级实战指南

快速体验 在开始今天关于 AIGC大模型系统化学习路径:从理论到工业级实战指南 的探讨之前,我想先分享一个最近让我觉得很有意思的全栈技术挑战。 我们常说 AI 是未来,但作为开发者,如何将大模型(LLM)真正落地为一个低延迟、可交互的实时系统,而不仅仅是调个 API? 这里有一个非常硬核的动手实验:基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。 从0到1构建生产级别应用,脱离Demo,点击打开 从0打造个人豆包实时通话AI动手实验 AIGC大模型系统化学习路径:从理论到工业级实战指南 背景痛点分析 当前开发者在AIGC应用落地过程中普遍面临三大核心挑战: 1. 模型选择困难症:开源模型如GPT-3、Claude、LLaMA等参数规模从7B到175B不等,不同架构的推理效果与计算成本差异显著。部分团队盲目追求大参数模型,导致推理延迟超标。

AMD显卡终极兼容指南:llama.cpp Vulkan后端快速解决方案

AMD显卡终极兼容指南:llama.cpp Vulkan后端快速解决方案 【免费下载链接】llama.cppPort of Facebook's LLaMA model in C/C++ 项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp 你是否在AMD显卡上运行llama.cpp时遇到过Vulkan初始化失败或推理速度异常的问题?本文为你提供一套完整的AMD显卡兼容性解决方案,让你轻松解决llama.cpp在AMD设备上的各种疑难杂症。通过本指南,你将掌握从驱动优化到性能调优的全套技巧,让大语言模型在AMD显卡上流畅运行。 AMD显卡兼容性问题深度解析 AMD显卡用户在使用llama.cpp的Vulkan后端时,主要面临三大挑战: 驱动版本不匹配:不同世代的AMD显卡对Vulkan API的支持程度存在差异,特别是RDNA架构的RX 6000/7000系列。 内存管理冲突:AMD的显存分配策略与llama.cpp的预期存在偏差,导致模型加载失败。 着色器编译异常:特定驱动版本在编译SPIR-V着色器时会产生无效

EpicDesigner快速上手指南:Vue3拖拽式低代码设计器

EpicDesigner快速上手指南:Vue3拖拽式低代码设计器 【免费下载链接】epic-designer 项目地址: https://gitcode.com/gh_mirrors/ep/epic-designer 项目快速了解 EpicDesigner是一款基于Vue3开发的现代化低代码设计器,它让页面开发变得像搭积木一样简单。无论你是前端新手还是资深开发者,都能通过拖拽组件的方式快速生成功能完整的页面。 环境准备清单 在开始安装之前,请确保你的开发环境满足以下要求: 必备条件: * Node.js 14.x 或更高版本 * npm 或 yarn 包管理器 * 现代浏览器(推荐Chrome、Firefox) 可选准备: * 熟悉Vue3基础概念 * 了解JSON数据结构 三步安装法 第一步:获取项目代码 git clone https://gitcode.com/gh_mirrors/ep/epic-designer 第二步:安装依赖