源: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

最新文章

  1. FastPolice项目总结
  2. [转] JAVA多线程和并发基础面试问答
  3. 第一次做的struts2与spring整合
  4. 254. Factor Combinations
  5. timus1004 最小环()Floyd 算法
  6. Java设计模式系列之策略模式
  7. 你知道C/S和B/S两种架构有什么区别吗?
  8. IIS中访问自己开发的Webservice site就自动停止,尝试重启IIS和重启服务器都不能解决。
  9. operator模块
  10. QLabel设置行间距(使用html的语法,比较巧妙)
  11. 快速进入pycharm图形界面
  12. 为什么我们要使用Async、Await关键字
  13. 如何彻底删除mysql
  14. poj-1459(网络流-最大流)
  15. click()和onclick()的区别
  16. 在同一个服务器(同一个IP)为不同域名绑定的免费SSL证书
  17. mac 安装Seaslog扩展及SeasLogger应用
  18. webgl opengl教程样例
  19. 680. Valid Palindrome II
  20. ELK学习笔记之ELK分析syslog日志

热门文章

  1. servlet第1讲初识
  2. 发现在看完objc基本语法之后,还是看Apple文档比较有用。
  3. input text中不能显示空格后的内容
  4. perl中调用cgi
  5. docker installation on ubuntu
  6. Timewarp 一种生成当中帧技术,异步时间扭曲(Asynchronous Timewarp)
  7. Tinyxml封装类COperatorXml
  8. Integer比较值的时候小心使用
  9. WebKit框架 浅析
  10. 自定义开关ToggleButton