数字信号处理基础(二):FFT和IFFT的使用以及详细分析代码书写思路

news/2024/12/15 14:48:27/

目录

  • 1. fft和ifft的原理
    • 1.1 fft
    • 1.2 ifft
  • 2. 书写代码思路
  • 3. 完整代码
  • 4. 结果图

1. fft和ifft的原理

1.1 fft

fft是快速傅里叶变换,是MATLAB中计算信号频谱的函数,使用方法是fft(x),直接对信号x进行fft计算。
由于fft函数计算信号的频谱是0-fs范围的,但是我们更习惯观察的信号的双边频谱,即-fs/2-fs/2范围的频谱,因此常用fftshift(x)函数将0-fs范围的信号频谱搬移到-fs/2-fs/2范围,也就是将原来0-fs范围中的fs/2-fs范围的频谱搬移到-fs/2-0范围处。

1.2 ifft

ifft是快速逆傅里叶变换,是MATLAB中求信号的逆傅里叶变换的函数,使用方法是ifft(x)。

2. 书写代码思路

1.养成良好习惯,在代码的最上面书写三件套代码,该清除的清除。

clear all;                  % 清除所有变量
close all;                  % 关闭所有窗口
clc;                        % 清屏

2.确定各个信号的频率以及信号的最高频率,本例中信号是正弦信号和余弦信号之和,分别确定各个信号频率,以及信号的最高频率,这里是3000Hz

fc1 = 1000;                 % 信号1的中心频率
fc2 = 3000;                 % 信号2的中心频率

3.根据信号的最高频率和奈奎斯特采样定理确定采样频率(大于信号最高频率的2倍即可),本人为了时域信号的平滑,通常将采样频率设置为最高频率的30倍左右。

fs = 100000;                % 采样频率,满足奈奎斯特采样定理即可,这里为信号频率的33倍原因是为了采样点数多,时域波形平滑

4.根据采样频率求得采样间隔,即采样频率的倒数

dt = 1/fs;                  % 采样间隔

5.确定仿真信号时长,这个一般根据实际情况来定,例如在通信系统中,首先需要确定码元周期,然后确定码元个数,两者相乘即是仿真时长,在本例中设置的时长是0.1。

T = 0.1;                    % 采样总时长

6.确定采样点数,为采样时长除以采样间隔。

N = T*fs;                   % 采样点数,N=T/dt=T*fs

7.确定仿真时间变量,从0开始,以采样间隔为间隔,形成1*N的行向量

t = 0:dt:(N-1)*dt;          % 时间行向量,间隔为dt

8.产生信号,并且绘制图像。

sig = sin(2*pi*fc1*t)+cos(2*pi*fc2*t);% 信号
figure(1);                  % 绘制第1幅图
plot(t,sig,'LineWidth',2);  % 绘制信号波形
axis([0 0.002 -2 2]);       % 坐标轴范围设置
xlabel('时间/t');           % 横坐标标签
ylabel('幅值');             % 纵坐标
title('原始信号');          % 标题
grid on;                    % 打开网格线

9.对信号进行fft,fft三步走

sig_f = fft(sig);           % 对信号进行fft
sig_f_2 = abs(sig_f);       % fft后取绝对值得到幅度响应
sig_f_2 = fftshift(sig_f_2);%0-fs频谱移动到-fs/2-fs/2

10.确定频谱分辨率fs/N=1/T

df = 1/T;                   % 频谱分辨率fs/N=1/T

11.确定频谱范围,即-fs/2-fs/2,间隔为频谱分辨率

f=(-N/2:N/2-1)*df;          % 频率范围

12.绘制频谱

figure(2);                  % 绘制第2幅图
plot(f,sig_f_2,'LineWidth',2);% 绘制信号的频谱
axis([-5000 5000 -inf inf]);% 坐标轴范围设置
xlabel('频率/Hz');          % 横坐标标签
ylabel('幅值');             % 纵坐标
title('原始信号的频谱');    % 标题
grid on;                    % 打开网格线

13.对信号做ifft,这里是对fft后的信号sig_f进行ifft,而不是对进行fft三步走后的信号sig_f_2进行ifftshift,然后进行ifft,因为三步走中有一步是取绝对值,通过ifftshift然后ifft无法准确还原出原始信号,因此为了还原出原始信号,应该对fft后的信号sig_f进行ifft,这也是为什么要三步走的原因,而不采用一行生成的代码fftshift(abs(fft(x)))。

sig_ifft = ifft(sig_f);     % 对fft后的信号进行ifft还原成时域信号

14.绘制还原后信号图像

plot(t,sig_ifft,'LineWidth',2);% 绘制还原后的时域信号
axis([0 0.002 -2 2]);       % 坐标轴范围设置
xlabel('时间/t');           % 横坐标标签
ylabel('幅值');             % 纵坐标
title('还原后信号');        % 标题
grid on;                    % 打开网格线

3. 完整代码

clear all;                  % 清除所有变量
close all;                  % 关闭所有窗口
clc;                        % 清屏
%% 基本参数
fc1 = 1000;                 % 信号1的中心频率
fc2 = 3000;                 % 信号2的中心频率
fs = 100000;                % 采样频率,满足奈奎斯特采样定理即可,这里为信号频率的33倍原因是为了采样点数多,时域波形平滑
dt = 1/fs;                  % 采样间隔
T = 0.1;                    % 采样总时长
N = T*fs;                   % 采样点数,N=T/dt=T*fs
t = 0:dt:(N-1)*dt;          % 时间行向量,间隔为dt
sig = sin(2*pi*fc1*t)+cos(2*pi*fc2*t);% 信号
figure(1);                  % 绘制第1幅图
plot(t,sig,'LineWidth',2);  % 绘制信号波形
axis([0 0.002 -2 2]);       % 坐标轴范围设置
xlabel('时间/t');           % 横坐标标签
ylabel('幅值');             % 纵坐标
title('原始信号');          % 标题
grid on;                    % 打开网格线
sig_f = fft(sig);           % 对信号进行fft
sig_f_2 = abs(sig_f);       % fft后取绝对值得到幅度响应
sig_f_2 = fftshift(sig_f_2);%0-fs频谱移动到-fs/2-fs/2
df = 1/T;                   % 频谱分辨率fs/N=1/T
f=(-N/2:N/2-1)*df;          % 频率范围
figure(2);                  % 绘制第2幅图
plot(f,sig_f_2,'LineWidth',2);% 绘制信号的频谱
axis([-5000 5000 -inf inf]);% 坐标轴范围设置
xlabel('频率/Hz');          % 横坐标标签
ylabel('幅值');             % 纵坐标
title('原始信号的频谱');    % 标题
grid on;                    % 打开网格线
sig_ifft = ifft(sig_f);     % 对fft后的信号进行ifft还原成时域信号
figure(3);                  % 绘制第3幅图
plot(t,sig_ifft,'LineWidth',2);% 绘制还原后的时域信号
axis([0 0.002 -2 2]);       % 坐标轴范围设置
xlabel('时间/t');           % 横坐标标签
ylabel('幅值');             % 纵坐标
title('还原后信号');        % 标题
grid on;                    % 打开网格线

4. 结果图

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/news/72398.html

相关文章

Unity之OpenXR+XR Interaction Toolkit示例Demo详解

一.前言 自从升级Unity版本到2021,然后使用OpenXR开发VR之后,我们整个团队的开发效率都提升了不少,这证明了不管什么领域,统一接口,统一规范都是必须的。 关于XR Interaction Toolkit插件,我已经写了几篇文章了,今天才想起来,最基础的Demo讲解还没有写,其实官方的这个…

Burpsuite模块—-Intruder模块详解

一、简介 Burp Intruder是一个强大的工具,用于自动对Web应用程序自定义的攻击,Burp Intruder 是高度可配置的,并被用来在广范围内进行自动化攻击。你可以使用 Burp Intruder 方便地执行许多任务,包括枚举标识符,获取有…

华为云——代码托管的使用

一、打开前后端项目 登录华为云,点击页面右上角的用户名——点击个人设置 2.点击代码托管的HTTPS密码管理,设置自己的密码 3.回到代码仓库,复制HTTP地址 4.打开GitHubDesktop,点击左上角进行仓库克隆 (我这里已经cl…

大学毕业设计这样做可以吗

前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…

linux内核篇-输入输出系统(块设备,字符设备)

计算机系统的输入和输出系统都有哪些呢?有键盘、鼠标、显示器、网卡、硬盘、打印机、CD/DVD 等等,多种多样。但是对于操作系统来讲,却是一件复杂的事情,因为这么多设备,形状、用法、功能都不一样,怎么才能统…

三、Spring Cache + Redis 缓存数据

文章目录 一、Spring Cache Redis 缓存数据1、项目集成Spring Cache Redis1.1 service-util添加依赖1.2 service-util添加配置类1.3 service-cmn添加redis配置 2、使用Spring Cache2.1 常用缓存标签2.1.2 缓存Cacheable2.1.2 缓存CachePut2.1.3 缓存CacheEvict 2.2 数据字典应…

FreeRTOS_系统配置

目录 1. FreeRTOSConfig.h 文件 2. "INCLUDE_" 开始的宏 2.1 INCLUDE_xSemaphoreGetMutexHolder 2.2 INCLUDE_xTaskAbortDelay 2.3 INCLUDE_vTaskDelay 2.4 INCLUDE_vTaskDelayUntil 2.5 INCLUDE_vTaskDelete 2.6 INCLUDE_xTaskGetCurrentTaskHandle 2.7 IN…

System::TrackStereo

unique_lock<mutex> lock2(mMutexState); mTrackingState = mpTracker->mState; mTrackedMapPoints = mpTracker->mCurrentFrame.mvpMapPoints; mTrackedKeyPointsUn = mpTracker->mCurrentFrame.mvKeysUn;这段代码使用了unique_lock<mutex>和mMutexState…