DSP常见算法的实现
FFT算法的DSP实现

FFT 算法的DSP 实现对于离散傅里叶变换(DFT)的数字计算,FFT是一种有效的方法。
一般假定输入序列是复数。
当实际输入是实数时,利用对称性质可以使计算DFT 非常有效。
一个优化的实数FFT算法是一个组合以后的算法。
原始的2N个点的实输入序列组合成一个N 点的复序列,之后对复序列进行N 点的FFT 运算,最后再由N 点的复数输出拆散成2N点的复数序列,这 2 N点的复数序列与原始的2N点的实数输入序列的DFT输出一致。
使用这种方法,在组合输入和拆散输出的操作中,FFT 运算量减半。
这样利用实数FFT 算法来计算实输入序列的DFT的速度几乎是一般FFT算法的两倍。
下面用这种方法来实现一个256 点实数FFT(2N=256 )运算。
1. 实数FFT 运算序列的存储分配如何利用有限的DSP 系统资源,合理的安排好算法使用的存储器是一个比较重要的问题。
本文中,程序代码安排在0x3000 开始的存储器中,其中0x3000~0x3080 存放中断向量表,FFT程序使用的正弦表和余弦表数据(.data段)安排在OxcOO开始的地方,变量(.bss段定义)存放在0x80 开始的地址中。
另外,本文中256 点实数FFT 程序的数据缓冲位Ox23OO~Ox23ff , FFT 变换后功率谱的计算结果存放在Ox22OO~Ox22ff 中。
连续定位.cmd 文件程序如下:MEMORY {PAGE O: IPROG: origin = Ox3O8O,len=Ox1F8OVECT: lorigin=Ox3OOO,len=Ox8OEPROG: origin=Ox38OOO,len=Ox8OOOPAGE 1:USERREGS: origin=Ox6O,len=Ox1cBIOSREGS: origin=Ox7c,len=Ox4IDATA: origin=Ox8O,len=OxB8O}SECTIONS{EDATA: origin=OxCOO,len=Ox14OO{.vectors: { } > VECT PAGE O.sysregs:.trcinit:.gblinit: { } > BIOSREGS PAGE 1 { } > IPROG PAGE O { } > IPROG PAGE O.bios:frt:{ } > IPROG PAGE O { } > IPROG PAGE O.text: { } > IPROG PAGE O.cinit: { } > IPROG PAGE O.pinit: { } > IPROG PAGE O.sysinit: { } > IPROG PAGE O.data: .bss: .far:.const: { } > EDATA PAGE 1 { } > IDATA PAGE 1 { } > IDATA PAGE 1 { } > IDATA PAGE 1.switch: { } > IDATA PAGE 1 .sysmem: { } > IDATA PAGE1•cio:{ } > IDATA PAGE1.MEM$obj: { } > IDATA PAGE1.sysheap: { } > IDATA PAGE1}2.基2实数FFT运算的算法该算法主要分为以下四步进行:1)输入数据的组合和位排序首先,原始输入的2N=256个点的实数序列复制放到标记有“ d_input_addr "的相邻单元,当成N=128点的复数序列d[n],其中奇数地址是d[n]实部,偶数地址是d[n]的虚部,这个过程叫做组合(n为序列变量,N为常量)。
DSP软件编程及算法实现

VIP专享文档下载特权自VIP生效起每月发放一次, 每次发放的特权有效期为1个月,发放数量由您购买 的VIP类型决定。
每月专享9次VIP专享文档下载特权, 自VIP生效起每月发放一次,持续有 效不清零。自动续费,前往我的账号 -我的设置随时取消。
服务特 权
共享文档下载特权
VIP用户有效期内可使用共享文档下载特权下载任意下载券标价的文档(不含付费文档和VIP专享文档),每下载一篇共享文
定点运算中数的定标
在定点DSP中,都是采用定点数进行数值运算,其操 作数一般采用整型数来表示。而许多算法的仿真往往 是使用浮点数进行的。
对于定点DSP编程来说,数的定标是一个关键性的问 题
对于16位的DSP而言,由程序员来确定一个数的小数 点将处于16位中的哪一位。
我们可以用Q,S法来表示,不同的表示方法所带来的 数的范围和精度的
简单谈一下COFF文件格式
TI 公司的汇编器和链接器创建的目标文件采用一种称 为COFF(Common Object File Format)。公共目标文 件格式
采用这种格式的目的是为了模块化编程的方便。通过 这种格式,程序员可以自己进行代码段的管理和目标 系统存储器的管理。
在COFF文件格式中,程序员在编程时是基于代码段的 概念。
仿真结果
输出滤波器系数
采用C语言进行仿真
在DSP的C编译器出现以前,C语言担当的主要是算法 仿真的角色。与MATLAB相比、它没有强大的工具软 件包。但它的优势是可以很快地形成商业化软件,另 外由于历史原因,国际上的各种算法的交流,都是在 UNIX平台上,用C语言编写。所以C也成为被广泛使 用的仿真工具。
DSP算法的仿真
选择仿真工具 常用的算法仿真工具 MATLAB、C
DSP实现FFT的代码

DSP实现FFT的代码FFT(快速傅里叶变换)是一种用于高效计算离散傅里叶变换(DFT)的算法。
在数字信号处理(DSP)中,FFT常被用来进行频域分析、滤波和信号压缩等操作。
下面是一个使用C语言实现FFT的代码示例:```c#include <stdio.h>#include <math.h>//基于蝴蝶算法的FFT实现if (N <= 1) return;for (int i = 0; i < N / 2; i++)even[i] = x[2*i];odd[i] = x[2*i+1];}fft(even, N / 2);fft(odd, N / 2);for (int k = 0; k < N / 2; k++)x[k] = even[k] + t;x[k + N/2] = even[k] - t;}free(even);free(odd);//对输入信号进行FFT变换fft(x, N);//打印复数数组for (int i = 0; i < N; i++)printf("(%f,%f) ", creal(arr[i]), cimag(arr[i]));}printf("\n");int maiint N = 8; // 信号长度printf("原始信号为:\n");fft_transform(x, N);printf("FFT变换后的结果为:\n");return 0;```在这个代码示例中,我们首先定义了一个基于蝴蝶算法的FFT实现函数,然后使用该函数对输入信号进行傅里叶变换。
最后,我们通过打印的方式输出了原始信号和经过FFT变换后的结果。
需要注意的是,FFT是一个复杂的算法,需要理解较多的数学知识和算法原理。
在实际应用中,可以使用现成的DSP库或者软件工具来进行FFT计算,以提高效率和准确性。
dsp原理及应用技术 pdf

dsp原理及应用技术 pdf
DSP(Digital Signal Processing)即数字信号处理,是利用数
字计算机来对连续或离散时间的信号进行采样、量化、编码和数字算法处理的技术。
它通过数字计算手段对信号进行采样、滤波、谱分析、编码压缩等处理,能够更加精确和灵活地分析和处理各种类型的信号。
DSP技术广泛应用于通信、音频、视频、雷达、医学图像处理、语音识别、控制系统等领域。
以下是几种常见的DSP应
用技术:
1. 数字滤波:通过数字滤波器实现对输入信号的滤波功能,包括低通滤波、高通滤波、带通滤波等,可用于信号去噪、频率选择等应用。
2. 数据压缩:通过数学算法对信号进行压缩编码,减少数据存储和传输的带宽需求,如音频压缩算法(MP3)、图像压缩算法(JPEG)等。
3. 语音处理:利用DSP技术对语音信号进行去噪、增强、压缩、识别等处理,可应用于语音通信、语音识别、语音合成等领域。
4. 图像处理:通过DSP算法对图像进行增强、分割、检测等
处理,广泛应用于医学图像处理、目标检测、图像识别等领域。
5. 音频处理:通过DSP技术对音频信号进行均衡、混响、降
噪、音效处理等,可应用于音频播放、音效合成、音乐处理等领域。
6. 通信信号处理:包括调制解调、信号解码、信道均衡等处理,用于移动通信、无线电频谱分析、信号检测等应用。
7. 实时控制系统:通过DSP算法对反馈信号进行采样和处理,实现控制系统的实时控制和调节,如机器人控制、自动驾驶等。
总之,DSP技术在各个领域都发挥着重要作用,通过数字计
算的精确性和灵活性,能够高效地处理和分析各种类型的信号,满足不同应用的需求。
基于DSP的音频信号处理算法研究与实现

基于DSP的音频信号处理算法研究与实现音频信号处理是一项关键技术,它在实际生活和各个领域中得到广泛应用。
基于数字信号处理器(DSP)的音频信号处理算法研究与实现,成为了当前研究和开发的热点方向。
本文将探讨利用DSP实现音频信号处理算法的研究方法和具体实现步骤。
1. DSP的概述DSP(Digital Signal Processing,数字信号处理)技术是指利用数字化方法对模拟信号进行处理、计算和编码的技术。
它通过数字滤波、数字变换等算法对数字信号进行处理,具有高效性、灵活性和精确性等优势。
DSP技术在音频处理领域有着重要的应用。
2. 音频信号处理算法研究方法2.1 问题分析:首先需要明确要处理的音频信号处理问题,例如降噪、滤波、均衡等。
针对不同的处理问题,选择合适的算法进行研究。
2.2 算法选择:根据具体问题的特点,选择适合的音频信号处理算法,例如自适应滤波算法、小波变换算法等。
2.3 算法实现:将选择的算法进行进一步实现,需要借助DSP的开发环境和相应的软件工具进行编程和调试。
算法的实现过程中需要注意算法的时效性和实时性。
3. DSP音频信号处理算法实现步骤3.1 信号采集:通过外设音频采集模块,将模拟音频信号转换为数字信号,输入DSP进行处理。
3.2 数据预处理:对采集到的音频信号进行预处理,包括滤波、去噪等操作。
这一步旨在减小输入信号的噪声干扰,提高音频信号处理的质量。
3.3 算法实现:选择适当的音频信号处理算法进行实现,例如自适应滤波、小波变换等。
根据算法的特点和要求,进行程序编写和调试。
3.4 数据后处理:将处理后的数字音频信号转换为模拟信号,经过后续的数模转换模块,输出音频信号。
4. 实例分析:音频降噪算法在DSP上的实现以音频降噪算法为例,介绍基于DSP的音频信号处理算法的具体实现步骤。
4.1 问题分析:降噪算法是音频信号处理中常见的问题,通过去除背景噪声提升原始信号的质量。
4.2 算法选择:选择适合的降噪算法,例如基于自适应滤波的降噪算法,通过实时估计噪声模型并进行滤波处理。
数字信号处理中常见的算法和应用

数字信号处理中常见的算法和应用数字信号处理(DSP)是一门研究数字信号在处理上的方法和理论的学科。
它涉及到数字信号的获取、转换、分析和处理等过程。
在数字信号处理中,有一些常见的算法和应用,在本文中我将详细介绍它们的内容和步骤。
1. 快速傅里叶变换(FFT)算法快速傅里叶变换是一种高效的离散傅里叶变换(DFT)算法,它能够将离散时间序列的信号转换到频域中,得到信号的频谱信息。
FFT算法广泛应用于音频信号处理、图像处理、通信系统等领域。
其基本步骤如下:a. 将信号补零,使其长度为2的整数次幂;b. 利用蝶形运算的方法,迭代计算信号的DFT;c. 得到信号在频域中的表示结果。
2. 自适应滤波算法自适应滤波是一种能够根据输入信号的特点自动调整滤波参数的方法。
在实际应用中,自适应滤波经常用于降噪、回声消除和信号增强等方面。
以下是一种自适应滤波的算法步骤:a. 根据系统的特性和输入信号的统计特征,选择一个合适的滤波器结构和模型;b. 初始化滤波器参数;c. 利用最小均方(LMS)估计算法,不断迭代更新滤波器参数,使得滤波器的输出和期望输出之间的误差最小化。
3. 数字滤波器设计算法数字滤波器是数字信号处理中常用的工具,它能够通过改变信号的频谱来实现对信号的去噪、信号重构和频率选择等功能。
常见的数字滤波器设计算法有以下几种:a. Butterworth滤波器设计算法:将滤波器的频率响应设计为最平坦的,同时保持较低的滚降;b. Chebyshev滤波器设计算法:在频域中,较好地平衡了通带的校正和滤波器的滚降;c. FIR滤波器设计算法:利用有限长冲激响应的特性,通过改变滤波器的系数来调整滤波器的频率响应。
4. 数字信号压缩算法数字信号压缩是一种减少信号数据存储和传输所需的比特数的方法,常见的压缩算法有以下几种:a. 哈夫曼编码:通过对信号进行频率统计,将出现频率较高的符号用较少的比特表示;b. 等分连续衰减编码(PCM):将连续的信号量化,用有限比特数来近似连续的信号值,从而减少数据的表示位数;c. 变换编码:通过变换信号的编码形式,将一组相关的信号值映射到一组或更少的比特上。
基于DSP的数据采集及FFT实现

基于DSP的数据采集及FFT实现基于数字信号处理器(DSP)的数据采集和快速傅里叶变换(FFT)实现在信号处理和频谱分析等领域具有广泛的应用。
通过使用DSP进行数据采集和FFT实现,可以实现高速、高精度和实时的信号处理。
首先,数据采集是将模拟信号转换为数字信号的过程。
数据采集通常涉及到模拟到数字转换器(ADC),它将模拟信号进行采样并进行量化,生成离散的数字信号。
DSP通常具有内置的ADC,可以直接从模拟信号源获取数据进行采集。
采集到的数据可以存储在DSP的内存中进行后续处理。
数据采集的关键是采样频率和采样精度。
采样频率是指在单位时间内采集的样本数,它决定了采集到的频谱范围。
采样频率需要满足奈奎斯特采样定理,即至少为信号最高频率的2倍。
采样精度是指每个采样点的位数,它决定了采集到的数据的精确程度。
常见的采样精度有8位、16位、24位等。
在数据采集之后,可以使用FFT算法对采集到的数据进行频谱分析。
FFT是一种用于将时间域信号转换为频域信号的算法,它能够将连续时间的信号转换为离散频率的信号。
FFT算法的核心是将复杂度为O(N^2)的离散傅里叶变换(DFT)算法通过分治法转化为复杂度为O(NlogN)的算法,使得实时处理大规模数据成为可能。
在使用DSP进行FFT实现时,可以使用DSP芯片内置的FFT模块,也可以通过软件算法实现FFT。
内置的FFT模块通常具有高速运算和低功耗的优势,可以在较短的时间内完成大规模数据的FFT计算。
软件算法实现FFT较为灵活,可以根据实际需求进行调整和优化。
通常,FFT实现涉及到数据的预处理、FFT计算和结果后处理。
数据的预处理通常包括去除直流分量、加窗等操作,以减小频谱泄漏和谱漂的影响。
FFT计算是将采集到的数据通过FFT算法转换为频域信号的过程。
结果后处理可以包括频谱平滑、幅度谱归一化、相位分析等。
通过合理的数据预处理和结果后处理,可以获得准确的频谱信息。
除了基本的数据采集和FFT实现,基于DSP的数据采集和FFT还可以进行其他扩展和优化。
基于DSP的FFT算法实现

基于DSP的FFT算法实现1、 FFT的原理快速傅氏变换(FFT)是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。
它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。
设x(n)为N项的复数序列,由DFT变换,任一X(m)的计算都需要N次复数乘法和N-1次复数加法,而一次复数乘法等于四次实数乘法和两次实数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出N项复数序列的X(m),即N点DFT 变换大约就需要N2次运算。
当N=1024点甚至更多的时候,需要N2=1048576次运算,在FFT中,利用WN的周期性和对称性,把一个N项序列(设N=2k,k为正整数),分为两个N/2项的子序列,每个N/2点DFT变换需要(N/2)2次运算,再用N次运算把两个N/2点的DFT变换组合成一个N点的DFT变换。
这样变换以后,总的运算次数就变成N+2(N/2)2=N+N2/2。
继续上面的例子,N=1024时,总的运算次数就变成了525312次,节省了大约50%的运算量。
而如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT运算单元,那么N点的DFT 变换就只需要Nlog2N次的运算,N在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT的优越性。
数字信号处理器(DSP)是一种可编程的高性能处理器,近年来发展很快.它不仅适用于数字信号处理,而且在图像处理、语音处理、通信等领域得到了广泛的应用.通用的微处理器在运算速度上很难适应信号实时处理的要求.联沪处理器中集成有高速的乘法器硬件,能快速地进行大量数据的乘法和加法运算。
快速傅里叶变换(FFT)的出现使得DFr在实际应用中得到了广泛的应用.2、基于DSP的FFT算法实现用C语言实现FFT算法/*****************fft programe*********************/ #include "typedef.h"#include "math.h"struct compx EE(struct compx b1,struct compx b2) {struct compx b3 ;b3.real=b1.real*b2.real-b1.imag*b2.imag ;b3.imag=b1.real*b2.imag+b1.imag*b2.real ;return(b3);}void FFT(struct compx*xin,int N){int f,m,nv2,nm1,i,k,j=1,l ;/*int f,m,nv2,nm1,i,k,j=N/2,l;*/struct compx v,w,t ;nv2=N/2 ;f=N ;for(m=1;(f=f/2)!=1;m++){;}nm1=N-1 ;/*变址运算*/for(i=1;i<=nm1;i++){if(i<j){t=xin[j];xin[j]=xin[i];xin[i]=t ;}k=nv2 ;while(k<j){j=j-k ;k=k/2 ;}j=j+k ;}{int le,lei,ip ;float pi ;for(l=1;l<=m;l++){le=pow(2,l);// 这里用的是L而不是1 lei=le/2 ;pi=3.14159 ;v.real=1.0 ;v.imag=0.0 ;w.real=cos(pi/lei); w.imag=-sin(pi/lei);for(j=1;j<=lei;j++){/*double p=pow(2,m-l)*j;double ps=2*pi/N*p;w.real=cos(ps);w.imag=-sin(ps);*/for(i=j;i<=N;i=i+le){/* w.real=cos(ps);w.imag=-sin(ps);*/ip=i+lei ;t=EE(xin[ip],v);xin[ip].real=xin[i].real-t.real ;xin[ip].imag=xin[i].imag-t.imag ;xin[i].real=xin[i].real+t.real ;xin[i].imag=xin[i].imag+t.imag ;}v=EE(v,w);}}}return ;}/*****************main programe********************/#include<math.h>#include<stdio.h>#include<stdlib.h>#include "typedef.h"float result[257];struct compx s[257];int Num=256 ;const float pp=3.14159 ;main(){int i=1 ;for(;i<0x101;i++){s[i].real=sin(pp*i/32);s[i].imag=0 ;}FFT(s,Num);for(i=1;i<0x101;i++){result[i]=sqrt(pow(s[i].real,2)+pow(s[i].imag,2)); }}3、ICETEK-F2812-A的实验板调试步骤1.实验准备(1)连接实验设备:(2)准备信号源进行AD 输入。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3.6 常见的算法实现在实际应用中虽然信号处理的方式多种多样,但其算法的基本要素却大多相同,在本节中介绍几种较为典型的算法实现,希望通过对这些例子(单精度,16bit )的分析,能够让大家熟悉DSP 编程中的一些技巧,在以后的工作中可以借鉴,达到举一反三的效果。
1. 函数的产生在高级语言的编程中,如果要使用诸如正弦、余弦、对数等数学函数,都可以直接调用运行库中的函数来实现,而在DSP 编程中操作就不会这样简单了。
虽然TI 公司提供的实时运行库中有一些数学函数,但它们所耗费的时间大多太长,而且对于大多数定点程序使用双精度浮点数的返回结果有点“大材小用”的感觉,因此需要编程人员根据自身的要求“定制”数学函数。
实现数学函数的方法主要有查表法、迭代法和级数逼近法等,它们各有特点,适合于不同的应用。
查表法是最直接的一种方法,程序员可以根据运算的需要预先计算好所有可能出现的函数值,将这些结果编排成数据表,在使用时只需要根据输入查出表中对应的函数值即可。
它的特点是速度快,但需要占用大量的存储空间,且灵活度低。
当然,可以对上述查表法作些变通,仅仅将一些关键的函数值放置在表中,对任意一个输入,可根据和它最接近的数据采用插值方法来求得。
这样占用的存储空间有所节约,但数值的准确度有所下降。
迭代法是一种非常有用的方法,在自适应信号处理中发挥着重要的作用。
作为函数产生的一种方法,它利用了自变量取值临近的函数值之间存在的关系,如时间序列分析中的AR 、MA 、ARMA 等模型,刻画出了信号内部的特征。
因为它只需要存储信号模型的参量和相关的状态变量,所以所占用的存储空间相对较少,运算时间也较短。
但它存在一个致命的弱点,由于新的数值的产生利用了之前的函数值,所以它容易产生误差累积,适合精度要求不高的场合。
级数逼近法是用级数的方法在某一自变量取值范围内去逼近数学函数,而将自变量取值在此范围外的函数值利用一些数学关系,用该范围内的数值来表示。
这种方法最大的优点是灵活度高,且不存在误差累积,数值精度由程序员完全控制。
该方法的关键在于选择一个合适的自变量取值区间和寻找相应的系数。
下面通过正弦函数的实现,具体对上述三种方法作比较。
查表法较简单,只需要自制一张数据表,也可以利用C5400 DSP ROM 内的正弦函数表。
迭代法的关键是寻找函数值间的递推关系。
假设函数采样时间间隔为T ,正弦函数的角频率为ω,那么可以如下推导:令()()()T T ωϕβϕαωϕ-+=+sin sin sin 等式的左边展开为T T side left ωϕωϕsin cos cos sin _+=等式的右边展开为()T T side right ωϕβωαϕsin cos cos sin _-+=对比系数,可以得到1,cos 2-==βωαT 。
令nT =ϕ,便可以得到如下的递推式: [][][]21cos 2---=n s n s T n s ω令[][]T A s s ωsin 2,01-=-=-,逐一迭代就能够获得采样间隔为T 的正弦序列了。
从迭代公式可以更清楚地看出,这种方法存在误差累积。
再来看级数逼近法,首先需要寻找一个合适的自变量取值区间和寻找相应的系数。
从正弦函数的对称性可知,只需要计算取值在],0[π内的函数就可以推断出所有取值范围内的函数。
接下来寻找系数,对于()x sin 可以作如下变换()()sin_new(y)sin sin ==y x π,那么y 的取值范围在]1,0[内,而sin_new( )与sin( )同构,所以在下面的分析中将sin_new( )替代sin( ),提到的正弦函数即指sin_new( )。
若汇编编程时采用的数据为Q15格式,那么取值与实际的弧度的对应关系如下图所示。
π2π-图3- 算法取值与弧度的对应关系在]1,0[内,正弦函数的修正级数(五次)展开如下式: 54321.800293x0.5446778x5.325196x-x0.02026367 3.140625x sin_new(x)+++=根据上式,可以写出正弦函数的生成程序。
;compute polynomial stlm A, T ;T=x stm #SinePolyCoeff, AR2 ld *AR2+, 16, A ;AH=c5 ld*AR2+, 16, B ;BH=c4poly *AR2+ ;A=c5*x+c4poly *AR2+ ;A=c5*x^2+c4*x+c3 poly *AR2+ ;A=c5*x^3+c4*x^2+c3*x+c2 poly *AR2+ ;A=c5*x^4+c4*x^3+c3*x^2+c2*x+c1 mpya A sftaA, 3;adjust AH to Q15SinePolyCoeff: ;in Q12 format .word 0x1cce ; 1.800293 (coef for x^5 = c5).word 0x08b7 ; 0.5446778(coef for x^4 = c4).word 0xaacc ; -5.325196 (coef for x^3 = c3).word 0x0053 ; 0.02026367 (coef for x^2 = c2) .word 0x3240 ; 3.140625 (coef for x^1 = c1)在编程过程中,使用到了POLY 语句,它能够使多项式的计算简洁快速地完成。
该函数的结果可以通过实验X 来验证。
2. FIR 滤波器的实现FIR 滤波器由于具有线性相位而且延迟能够确定,因而在信号处理中广泛应用。
FIR 的基本模型如下图所示。
图3- FIR 模型其数学表达式为[][][]∑-=-=10N i i n x i h n y ,根据该表达式可以给出一种最为直接的实现形式。
直接形式中采用线性地址来存放数据,如图3- 所示。
图3- 直接形式程序中可以采用MACD 来实现程序如下: ld *(Input), A stl A, *(x_n)stm #x_n_Nm1, AR2 mpy *AR2-, #h_Nm1, B rpt#N-2macd *AR2-, h_Nm2, B程序首先将新的数据放置在x[n]处,然后对状态缓存由下而上计算,在循环语句中每执行一次状态变量自动向下移动一级,即自动更新。
它的计算量基本为N个时钟周期。
当然,数据存放还可以采用循环缓存。
另外,由于FIR的系数存在对称性,其结构如图3- 所示。
那么可以利用这个特点,实现更为快速的计算。
图3- 对称结构的FIR为计算方便将状态变量分别存放在两个缓存区间内,一块命名为Buffer_new,存放图3- 上半部分的数据,另一块命名为Buffer_old,存放图3- 下半部分的数据。
它们都当循环缓存使用,大小为FIR阶数的一半,即N/2(常数SIZE)。
根据上述原理编写的汇编程序如下:stm #Buffer_new, AR2stm #Buffer_old, AR3stm #SIZE, BKstm # -1, AR0fir_loop:;read inputld *(Input), Astl A, *AR2;filteringadd *AR2+0%, *AR3+0%, Arptz B, #SIZE-1firs *AR2+0%, *AR3+0%, FIR_Coeffsth B, *(Output) ;store outputmar *+AR2(2)%mar *AR3+%mvdd *AR2, *AR3+0% ;update bufferb fir_loop为方便理解,在图3- 中,将状态变量更新的过程标明,左边的是Buffer_new,右边的是Buffer_old。
开始时,指针AR2和AR3分别指向Buffer_new和Buffer_old中的x[0]与x[-19],将最“新”的数据存进Buffer_new(步骤1)。
利用FIRS实现FIR,结果放在BH中。
计算结束后,AR2和AR3分别指向x[-1]和x[-18](步骤2)。
然后调整AR2,让它指向Buffer_new 中最“老”的数据x[-9] (步骤3);调整AR3,让它指向Buffer_old中最“老”的数据x[-19](步骤4)。
接下来进行数据更新,将Buffer_new 中最“老”的数据放进Buffer_old 中,成为最“新”的数据。
最后AR2指向x[-9]的位置,这个位置将在下次计算时放置新的输入;AR3指向x[-18],即Buffer_old 中最“老”的数据,便于下次计算(步骤5)。
图3- 对称结构的FIR 实现中状态变量的更新利用对称结构的实现在计算量上有了减少,大约为N/2个时钟周期。
当然,利用上述结构必须注意安排好数据的位置,以保证能进行正常的循环寻址。
3. IIR 滤波器的实现IIR 滤波器也是数字信号处理的主要工具之一,但由于它不具备线性相位,而且无法准确知道其延迟,所以使用较FIR 少。
下面,来观察一下IIR 的结构,其数学表达式如下:∑∑==-+-=Mi N i i i i n y a i n x b n y 01][][][从其数学公式可以看出,我们可以仿照在FIR 处理来直接实现。
定义两段缓存分别对应于x[ ]和y[ ],然后采用类似于FIR 的计算方式,采用MACD 语句,便能很快地完成IIR 滤波。
在直接实现中同时需要保存x[ ]和y[ ],当其阶数较大时,会占用比较大的数据空间。
为此,我们来考察IIR 的另一种结构。
如图3- ,在这种结构中存储的状态变量为d[ ],所以存储空间大大地减少了。
图3- IIR 的另一种结构通过对FIR 和IIR 算法的分析,一方面向读者介绍这些基本处理中的设计技巧,另一方面也提醒读者在算法实现过程中应充分考察算法本身的特点,以求利用它们获得高效的运算和存储空间的节省。
4. FFT 的实现在信号处理中,为突出信号的特征,经常在时域和频域之间作变换,而傅立叶变换是这当中最为典型的。
基2的快速傅立叶变换有比特翻转排序和蝶形运算组成,前者在3.x 节已经作了介绍,这里着重介绍蝶形运算的实现。
蝶形运算是快速傅立叶变换中设计得极为精巧的部分,它充分揭示了傅立叶变换系数间内在的关系,而且还能实现同址计算,如图所示。
完成一次蝶形运算需要一次复数的乘法和两次复数的加法。
N图3- 蝶形运算的示意图对于时间抽取的FFT 而言,在其第一级是乘法的系数为0N W (也就是1),那么这个复数的乘法就名存实亡了,因而在计算FFT 时,第一级可以直接用复数的加法实现。
第一级的程序如下: ;*** stage 1 *** stm #0, BK ld#-1, ASMstm #FFT_Data, PX stm #FFT_Data+K_DA TA_IDX_1, QXld *PX, 16, A ;AH=PX.xstm #K_FFT_SIZE/2-1, BRC rptbd stage1end-1 stm #K_DA TA_IDX_1+1, AR0sub *QX, 16, A, B ;BH=PX.x-QX.x add *QX, 16, A;AH=PX.x+QX.xsth A, ASM, *PX+ st B, *QX+ ||ld *PX, A;AH=PX.y sub *QX, 16, A, B ;BH=PX.y-QX.y add *QX, 16, A;AH=PX.y+QX.ysth A, ASM, *PX+0 stB, *QX+0%|| ld *PX, A stage1end:在代码中,为方便与图3- 对应,使用.asg 伪指令将寄存器的名字替换成示意图中的表达方式,PX 和QX 分别指向蝶形运算的数据的地址。