最近在做SDADC的测试相关工作,涉及到SDADC的信噪比SNR的评估,查阅了一些资料,这里整理记录了相关信号处理和计算方法,分享给大家。因为python 里面有现成的FFT 计算包(scipy.fftpack),所以下面的计算都在python 中进行。
1, 所用的python工具包:
import numpy as np
from scipy.fftpack import fft
import matplotlib.pyplot as plt
import math
2, 计算频谱
def fft_cal_db (Fs,data):
N = len (data) # 信号长度
fft_wind = fft(data,N) # 调用scipy fft 函数计算频谱
FFT_vol = np.abs(fft_wind)/N*2 # 计算幅度谱
FFT_db = 20*np.log10(FFT_vol) # Vol to dB
x=np.linspace(0, N-1, N)*Fs/N # X频率坐标
Fre = x[range(int(N/2))] # 取一半, 0-Fs/2
FFT_db = FFT_db[range(int(N/2))] # 取一半, 0-Fs/2
return Fre, FFT_db, FFT_vol
上面的函数默认用固定采样点数的原始数据进行FFT 计算,相当于对被采样信号加了矩形窗,仅仅适用于相干采样(采样点数N 是Fs/fi 的整数倍, Fs是采样频率, fi 是信号频率, 参见相干采样在频谱分析中的应用与准则-CSDN博客), 否则会发生频谱泄露。相干采样对实际测试环境中有时候很难实现,特别的需要被采样信号的时钟基准要与采样系统的时钟基准同相,所以为了避免频谱泄露通常会对采样的信号加窗,典型的是使用汉宁窗, numpy 包中提供了汉宁窗函数
fft_wind = fft(data*np.hanning(N),N)
图1, 相干采样,没有频谱泄露
图2, 非相干采样, 有频谱泄露
图3, 非相干采样,加汉宁窗
对比图1到图3, 可见非相干采样,频谱泄露严重,计算出的信噪比很差与实际的信噪比出入很大,而加窗是有效果的,虽然信号和噪声功率都下降了,但信噪比计算基本准确,这里有一点也要额外注意,加窗后还是有一定的频谱泄露,这时就需要在计算信噪比的时候将泄露附近的频率分量都看成信号,其他作为噪声。
3, 计算SNR
根据FFT 计算出的频谱,给定信号频率, 信号带宽就可以计算给定带宽内的信噪比, 基本的原理是帕斯瓦尔定理, 类似于勾股定理。