zoukankan      html  css  js  c++  java
  • FIR滤波器的实现方法(转)

    源:http://blog.sina.com.cn/s/blog_493520900102uy26.html

    内容来自于上篇博文,第七章,FIR滤波器

    http://blog.sina.com.cn/s/blog_493520900102uxzu.html

     
    使用 FDATool工具,构建一个Kaiser窗低通滤波器,采样频率8kHz,生成滤波器系数:
     
    1)例程1
     
    文件 fir_fltcoeff.h,以浮点形式表示的量化后的滤波器系数
    //define the   FIR  filter  length
    #define   N_FIR  40
     
    float   h[N_FIR]  =  { ‐ 0.004314029307,‐ 0.013091321622,‐0.016515087727,
                      ‐0.006430584433,  0.009817876267, 0.010801880238,
                      ‐0.006567413713,‐ 0.016804829623, 0.000653253913,
                       0.022471280087,  0.010147131468,‐0.025657740989,
                      ‐0.026558960619,  0.023048392854, 0.050385290390,
                      ‐0.009291203588,‐ 0.087918503442,‐0.033770330014,
                       0.187334796517,  0.401505729848, 0.401505729848,
                       0.187334796517,‐ 0.033770330014,‐0.087918503442,
                      ‐0.009291203588,  0.050385290390, 0.023048392854,
                      ‐0.026558960619,‐ 0.025657740989, 0.010147131468,
                       0.022471280087,  0.000653253913,‐0.016804829623,
                      ‐0.006567413713,  0.010801880238, 0.009817876267,
                      ‐0.006430584433,‐ 0.016515087727,‐0.013091321622,
                      ‐0.004314029307   };
     
    实际电路用AIC3106,每次采样中断来临后读入一组数据,分别为左右声道的数据,各16位。中断服务程序将左声道的每个数据送入滤波器,然后从DAC电路输出滤波后的结果。右声道数据不变。
     
    文件 ISRs_Plus.c ,中断服务程序:
    // Welch, Wright, & Morrow, 
    // Real-time Digital Signal Processing, 2011
    // Modified by Mark Wickert February 2012 to include GPIO ISR start/stop postings
     
    ///////////////////////////////////////////////////////////////////////
    // Filename: ISRs_fir_float.c
    //
    // Synopsis: Interrupt service routine for codec data transmit/receive
    //           floating point FIR filtering with coefficients in *.h file
    //
    ///////////////////////////////////////////////////////////////////////
     
    #include "DSP_Config.h"
    #include "fir_fltcoeff.h"   //coefficients in float format
     
    // Function Prototypes
    long int rand_int(void);
      
    // Data is received as 2 16-bit words (left/right) packed into one
    // 32-bit word.  The union allows the data to be accessed as a single 
    // entity when transferring to and from the serial port, but still be 
    // able to manipulate the left and right channels independently.
     
    #define LEFT  0
    #define RIGHT 1
     
    volatile union {
    Uint32 UINT;
    Int16 Channel[2];
    } CodecDataIn, CodecDataOut;
     
     
    float x_buffer[N_FIR];       //buffer for delay samples
     
     
    interrupt void Codec_ISR()
    ///////////////////////////////////////////////////////////////////////
    // Purpose:   Codec interface interrupt service routine  
    //
    // Input:     None
    //
    // Returns:   Nothing
    //
    // Calls:     CheckForOverrun, ReadCodecData, WriteCodecData
    //
    // Notes:     None
    ///////////////////////////////////////////////////////////////////////
    {                    
    WriteDigitalOutputs(1); // Write to GPIO J15, pin 6; begin ISR timing pulse
    int i;
    float result = 0; //initialize the accumulator
     
     
      if(CheckForOverrun()) // overrun error occurred (i.e. halted DSP)
    return; // so serial port is reset to recover
     
      CodecDataIn.UINT = ReadCodecData(); // get input data samples
     
    //Work with Left ADC sample
    //x_buffer[0] = 0.25 * CodecDataIn.Channel[ LEFT];
    //Use the next line to noise test the filter
    x_buffer[0] = 0.125*((short) rand_int());//scale input by 1/8
     
    //Filtering using a 32-bit accumulator
    for(i=0; i< N_FIR; i++)
    {
    result += x_buffer[i] * h[i];
    }
    //Update filter history
    for(i=N_FIR-1; i>0; i--)
    {
    x_buffer[i] = x_buffer[i-1];
    }
     
    //Return 16-bit sample to DAC
    CodecDataOut.Channel[ LEFT] = (short) result;
    // Copy Right input directly to Right output with no filtering
    CodecDataOut.Channel[RIGHT] = CodecDataIn.Channel[ RIGHT];
    WriteCodecData(CodecDataOut.UINT); // send output data to  port
    WriteDigitalOutputs(0); // Write to GPIO J15, pin 6; end ISR timing pulse
    }
     
    //White noise generator for filter noise testing
    long int rand_int(void)
    {
    static long int a = 100001;
     
    a = (a*125) % 2796203;
    return a;
    }
     
    可以看出,中断服务程序是逐点响应的,每次来一个数据,都要做一次滤波器运算,并将原有的数据前移一位,将新数据追加在缓冲区末尾。
    float x_buffer[N_FIR]; // 用于保存现在的新值和过去的数值,长度与滤波器系数相同
    x_buffer[0] // 用于保存当前值
    x_buffer[1] // 保存过去前一点的值,以此类推
    h[0...39] // 滤波器系数
    result += x_buffer[i] * h[i]; // 当前点滤波器输出结果,循环从0到39
  • 相关阅读:
    DNS解析过程和DNS挟持
    TCP的流量控制和拥塞控制
    tcp连接的建立与释放
    DRBD分布式块设备复制
    rsync+inotify实现数据的实时备份
    nginx+tomcat网页动静分离配置
    基于mysql数据库集群的360度水平切割
    基于主从复制的Mysql双机热备+amoeba实现读写分离、均衡负载
    hexo安装
    centos7-minimal升级内核
  • 原文地址:https://www.cnblogs.com/LittleTiger/p/4373688.html
Copyright © 2011-2022 走看看