0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

數(shù)字濾波器是如何工作的

安費(fèi)諾傳感器學(xué)堂 ? 來源:安費(fèi)諾傳感器學(xué)堂 ? 2024-06-13 10:09 ? 次閱讀

之前我們在說明數(shù)字濾波器的時候,多為Python來進(jìn)行示例驗(yàn)證的。實(shí)際應(yīng)用中,多為C/C++,無論是在嵌入式系統(tǒng)中,還是PC機(jī)上,尤其對于時間或者實(shí)時性要求比較嚴(yán)格的情況下,C/C++應(yīng)該是我們的首選。

本文通過一個帶通濾波器的Python驗(yàn)證,再轉(zhuǎn)換到C++代碼模擬驗(yàn)證的實(shí)現(xiàn)過程說明數(shù)字濾波器是如何工作的。 我們先通過Python測試驗(yàn)證,并生成濾波器的參數(shù)數(shù)據(jù)。然后將獲取的參數(shù)用到C程序中重現(xiàn)濾波器。 先看圖,后查代碼。在測試中,我們生成了一個混有50Hz,110Hz和210Hz的模擬信號,然后通過濾波器保留50Hz的信號。

d0335a90-20af-11ef-91d2-92fbcf53809c.png

圖-1 濾波器的幅頻響應(yīng)(50Hz窄帶帶通)

d03715c2-20af-11ef-91d2-92fbcf53809c.png

圖-2 模擬信號的濾波前后

d04f2770-20af-11ef-91d2-92fbcf53809c.png

圖-3 模擬信號濾波前后的頻譜圖

相關(guān)python代碼:

import numpy as np
from scipy.signal import firwin, freqz, lfilter
import matplotlib.pyplot as plt


fs = 1000.0 # Sample frequency (Hz)
f0 = 50.0 # Frequency to be removed from signal (Hz)
Q = 30.0 # Quality factor
w0 = f0/(fs/2) # Normalized Frequency


# Design band-pass filter
b = firwin(81, [w0 - 0.02, w0 + 0.02], pass_zero=False, window='hamming')
#Outputcoefficients,wegotthecoefficients from this step
b_string = ', '.join(str(coef) for i, coef in enumerate(b))
print('{', b_string, '}')


# Generate frequency response
w, h = freqz(b, [1], worN=1024)


# Convert to Hz
freq = w * fs / (2 * np.pi)


# Plot filter response
plt.plot(freq, abs(h))
plt.title('Filter Frequency Response')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Gain')
plt.grid(True)
plt.show()


# Create a test signal
t = np.arange(0, 1.0, 1/fs) # Time vector
signal=np.sin(2*np.pi*210*t)+np.sin(2*np.pi*50*t)+np.sin(2*np.pi*110*t)#Testsignal


# Apply filter to the test signal
filtered_signal = lfilter(b, [1], signal)


# Original signal & filtered signal
plt.figure(figsize=(12, 8))
plt.subplot(211)
plt.plot(t[:500], signal[:500], color='blue')
plt.title('Original Signal')
plt.xlabel('Time [s]')
plt.grid()


plt.subplot(212)
plt.plot(t[:500], filtered_signal[:500], color='red')
plt.title('Filtered Signal')
plt.xlabel('Time [s]')
plt.tight_layout()
plt.grid()
plt.show()


# Compute and plot the frequency spectrum of signals
N = len(signal)
T = 1/fs
xf = np.linspace(0.0, 1.0/(2.0*T), N//2) # Frequency vector


# Compute FFT of original and filtered signals
fft_signal = np.fft.fft(signal)
fft_filtered = np.fft.fft(filtered_signal)


# Plot FFT of original signal
plt.figure(figsize=(12, 8))
plt.subplot(211)
plt.plot(xf, 2.0/N * np.abs(fft_signal[0:N//2]), color='blue')
plt.title('Original Signal FFT')
plt.xlabel('Frequency [Hz]')
plt.grid()


# Plot FFT of filtered signal
plt.subplot(212)
plt.plot(xf, 2.0/N * np.abs(fft_filtered[0:N//2]), color='red')
plt.title('Filtered Signal FFT')
plt.xlabel('Frequency [Hz]')
plt.grid()
plt.tight_layout()


plt.show()

濾波器通過C++語言的功能復(fù)現(xiàn)和驗(yàn)證。

d0678aea-20af-11ef-91d2-92fbcf53809c.png

圖-4 模擬信號經(jīng)C++濾波器的前后波形(取部分,請對照圖-2)

這里的測試過程中,模擬信號由代碼直接生成,然后經(jīng)濾波器處理后,將該模擬信號和經(jīng)濾波之后的信號數(shù)據(jù)全部存到csv文件中。在csv文件中,我們可以再現(xiàn)數(shù)據(jù)濾波前后的變化。 以下為濾波器的C++代碼,大家可以再優(yōu)化。直接上代碼。

#include 
#include 
#include 
#include 
#include 


#define SAMPLE_RATE 1000.0


using namespace std; // 聲明使用std命名空間


const double pi = 3.14159265358979323846;


// 模擬信號函數(shù)
vector generateSignal(int sampleRate, int seconds)
{
  vectorsignal(sampleRate * seconds);   //定義模擬信號的數(shù)組長度
  for (unsigned int i = 0; i < (unsigned int)(sampleRate * seconds); ++i)
  {
????//?包含50Hz,110Hz和210Hz信號
    signal[i] = sin((2 * pi * i * 50) / sampleRate) + sin((2 * pi * i * 210) / sampleRate) + sin((2 * pi * i * 110) / sampleRate);
  }
  return signal;
}


// 濾波器函數(shù)
vectorfilter(constvector&b,constvector&a,constvector&signal)
{
  vector output(signal.size());
  for (size_t i = 0; i < signal.size(); ++i)
  {
    for (size_t j = 0; j < b.size(); ++j)
    {
      if (i >= j)
      {
        output[i] += b[j] * signal[i - j];
      }
    }
    for (size_t j = 1; j < a.size(); ++j)
    {
      if (i >= j)
      {
        output[i] -= a[j] * output[i - j];
      }
    }
    output[i] /= a[0];
  }
  return output;
}


// 寫入文件函數(shù)
void writeToFile(const vector& signal, const vector& filtered_signal, const string &filename)
{
  ofstream file(filename);


  for (std::size_t i = 0; i < signal.size(); i++)
  {
    file << i/SAMPLE_RATE << ", " << signal[i] <<", "<< filtered_signal[i]<< "
";
??}
}
// 主函數(shù)
int main()
{
  // 系數(shù)
  vector b{0.0010175493084400998, 0.0010954624020866333, 0.001080635650435545, 0.0009293052645812359,
                   0.0005868808563577278, -8.138309855847798e-19, -0.0008644147524968251, -0.0019966389877814107,
                   -0.003323586744207458, -0.004696461345361978, -0.005892320462621699, -0.006633249964255378, 
                   -0.006623614506478284, -0.005601944833604465, -0.0034001773970723163, -7.334366341273803e-18, 
                   0.004425290874832446, 0.00949426225087417, 0.014634010415364655, 0.019132982942933127, 
                   0.022226796444847933, 0.023207550009729024, 0.021541722692400025, 0.01697833945185371, 
                   0.009628503914736117, -6.755395515820625e-18, -0.01102370844120733, -0.02226281209657117, 
                   -0.032372473621654914, -0.04001099412924139, -0.04402269970024527, -0.043609484958132556, 
                   -0.03846490807520255, -0.028848803480728435, -0.015588116829396594, -9.10410551538968e-18, 
                   0.016255406162706088, 0.031374390998733945, 0.04363491329762711, 0.051616779739690075, 
                   0.05438594145724075, 0.051616779739690075, 0.04363491329762711, 0.031374390998733945, 
                   0.016255406162706088, -9.10410551538968e-18, -0.015588116829396594, -0.028848803480728435, 
                   -0.03846490807520255, -0.043609484958132556, -0.04402269970024527, -0.0400109941292414, 
                   -0.032372473621654914, -0.022262812096571168, -0.01102370844120733, -6.755395515820627e-18, 
                   0.009628503914736117, 0.016978339451853702, 0.021541722692400025, 0.023207550009729034, 
                   0.022226796444847933, 0.01913298294293312, 0.014634010415364655, 0.009494262250874175, 
                   0.004425290874832446, -7.3343663412738e-18, -0.0034001773970723163, -0.005601944833604469, 
                   -0.006623614506478284, -0.006633249964255374, -0.005892320462621699, -0.00469646134536198, 
                   -0.003323586744207458, -0.001996638987781409, -0.0008644147524968251, -8.138309855847805e-19, 
                   0.0005868808563577278, 0.0009293052645812359, 0.001080635650435545, 0.0010954624020866333, 
                   0.0010175493084400998};
  vector a{1};


  // 生成模擬信號
  vector signal = generateSignal(1000, 1); // 1秒的模擬信號


  // 濾波處理
  vector output = filter(b, a, signal);


  // 寫入至csv文件
  writeToFile(signal, output, "output.csv");


  return 0;
}

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)字濾波器
    +關(guān)注

    關(guān)注

    4

    文章

    266

    瀏覽量

    46946
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7581

    瀏覽量

    135542
  • C++
    C++
    +關(guān)注

    關(guān)注

    21

    文章

    2090

    瀏覽量

    73404
  • python
    +關(guān)注

    關(guān)注

    54

    文章

    4756

    瀏覽量

    84283

原文標(biāo)題:數(shù)字濾波器(3)——C語言的模擬及驗(yàn)證

文章出處:【微信號:安費(fèi)諾傳感器學(xué)堂,微信公眾號:安費(fèi)諾傳感器學(xué)堂】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    使用FPGA構(gòu)建的數(shù)字濾波器設(shè)計(jì)方案

    本文簡要介紹了FIR數(shù)字濾波器的結(jié)構(gòu)特點(diǎn)和基本原理,提出基于FPGA和DSP Builder的FIR數(shù)字濾波器的基本設(shè)計(jì)流程和實(shí)現(xiàn)方案。##FIR 數(shù)字濾波器的詳細(xì)設(shè)計(jì)。
    發(fā)表于 07-24 15:30 ?8756次閱讀
    使用FPGA構(gòu)建的<b class='flag-5'>數(shù)字濾波器</b>設(shè)計(jì)方案

    中頻濾波器數(shù)字濾波器

    通過數(shù)字濾波器可以獲得很窄的帶寬。和模擬濾波器相比,理想的高斯濾波器可以實(shí) 現(xiàn)。數(shù)字濾波器在可接受的價(jià)格內(nèi)有更好的選擇性,如5級電路模擬濾波器
    發(fā)表于 10-13 09:22

    數(shù)字濾波器的主要特點(diǎn)

    ://www.gooxian.com/product_detail-9722.htm的工作方式與模擬濾波器完全不同模擬濾波器完全依靠電阻、電容、晶體管等電子元件組成的物理網(wǎng)絡(luò)實(shí)現(xiàn)濾波
    發(fā)表于 11-10 16:43

    數(shù)字濾波器的設(shè)計(jì)與應(yīng)用

    數(shù)字濾波器
    發(fā)表于 08-26 19:29 ?24次下載
    <b class='flag-5'>數(shù)字濾波器</b>的設(shè)計(jì)與應(yīng)用

    數(shù)字濾波器(DF)的基本結(jié)構(gòu)

    數(shù)字濾波器的基本結(jié)構(gòu):數(shù)字濾波器結(jié)構(gòu)的表示方法一. 數(shù)字濾波器的概念1.濾波器:指對輸入信號起濾波作用的裝置。2、當(dāng)輸入、輸出是離散信號,
    發(fā)表于 12-07 12:10 ?14次下載

    數(shù)字濾波器的結(jié)構(gòu)

    數(shù)字網(wǎng)絡(luò)的信號流圖表示 IIR數(shù)字濾波器的結(jié)構(gòu) FIR數(shù)字濾波器的結(jié)構(gòu)數(shù)字濾波器的格形結(jié)構(gòu)信號流圖的基本概念1、定義:信號流圖是一種有向圖,它用帶箭頭
    發(fā)表于 01-07 10:24 ?30次下載

    數(shù)字濾波器的原理及其設(shè)計(jì)

    本章介紹數(shù)字濾波器的原理及其設(shè)計(jì)。數(shù)字濾波器的設(shè)計(jì)是數(shù)字系統(tǒng)綜合的問題之一。所謂數(shù)字系統(tǒng)的綜合(synthesis)就是給出設(shè)計(jì)指標(biāo)的情況下,設(shè)計(jì)一個系統(tǒng)使之滿足設(shè)計(jì)指標(biāo)
    發(fā)表于 11-24 09:13 ?127次下載

    數(shù)字濾波器的設(shè)計(jì)實(shí)驗(yàn)

    數(shù)字濾波器的設(shè)計(jì)實(shí)驗(yàn) 一. 數(shù)字濾波器設(shè)計(jì):(1) 數(shù)字濾波器設(shè)計(jì)步驟:a. 整理給定的濾波器設(shè)計(jì)要求
    發(fā)表于 10-30 13:34 ?5666次閱讀
    <b class='flag-5'>數(shù)字濾波器</b>的設(shè)計(jì)實(shí)驗(yàn)

    什么是數(shù)字濾波器

    什么是數(shù)字濾波器 數(shù)字濾波器(digital filter)是由數(shù)字乘法器、加法器
    發(fā)表于 06-30 12:37 ?3936次閱讀
    什么是<b class='flag-5'>數(shù)字濾波器</b>

    數(shù)字濾波器,數(shù)字濾波器原理是什么?

    數(shù)字濾波器,數(shù)字濾波器原理是什么? 在信號處理領(lǐng)域中,對于信號處理的實(shí)時性、快速性的要求越來越高。而在許多信息處理過程中
    發(fā)表于 03-24 14:06 ?2.9w次閱讀

    24位96khz采樣CMOS的立體聲音頻∑-Δ數(shù)位類比轉(zhuǎn)換

    數(shù)字濾波器工作在8倍過采樣在96kHz采樣率,兩種滾性能可以選擇:夏普滾,或慢滾,如需要特定的應(yīng)用。PCM1716適合中高檔音響應(yīng)用程序,如CD,DVD音頻和音樂儀器,因?yàn)樵撛O(shè)備具有優(yōu)越的音頻動態(tài)性能,24位分辨率及96kHz采樣。 特征 增強(qiáng)多層次delta-sigma
    發(fā)表于 06-02 09:55 ?11次下載
    24位96khz采樣CMOS的立體聲音頻∑-Δ數(shù)位類比轉(zhuǎn)換<b class='flag-5'>器</b>

    數(shù)字濾波器的設(shè)計(jì)方法及步驟詳解

    本文首先介紹了數(shù)字濾波器的原理,其次介紹了數(shù)字濾波器分類,最后介紹了五種不同數(shù)字濾波器的設(shè)計(jì)方法與步驟。
    發(fā)表于 04-20 10:40 ?12.9w次閱讀
    <b class='flag-5'>數(shù)字濾波器</b>的設(shè)計(jì)方法及步驟詳解

    基于matlab的數(shù)字濾波器的設(shè)計(jì)及數(shù)字濾波器基本結(jié)構(gòu)

    本文主要介紹了基于matlab的數(shù)字濾波器的設(shè)計(jì)及數(shù)字濾波器基本結(jié)構(gòu)。
    發(fā)表于 06-05 08:00 ?27次下載

    FIR數(shù)字濾波器設(shè)計(jì)

    數(shù)字濾波器的輸入輸出均為數(shù)字信號,信號通過數(shù)字濾波器后,可以改變頻率成分的相對比例或?yàn)V除某些頻率成分。數(shù)字濾波器可以分為IIR數(shù)字濾波器和F
    的頭像 發(fā)表于 04-05 09:47 ?5464次閱讀

    數(shù)字濾波器是什么 數(shù)字濾波器的性能指標(biāo)

      數(shù)字濾波器的原理基于數(shù)字信號處理技術(shù)和濾波器算法,通過對離散時間信號進(jìn)行處理和濾波,實(shí)現(xiàn)對信號頻率的選擇性衰減和增強(qiáng)。數(shù)字濾波器的輸入信
    發(fā)表于 02-24 11:23 ?5181次閱讀