音频信号数字滤波与FFT分析一、实验目的: (2)二、实验内容: (2)三、实验所用主要部件结构说明: (3)1、TMS320F2812片内有1个带采样保持电路的12BIT的A/D转换模块 (3)(1)、ADC的特点: (3)(2)ADC管脚信号 (3)1)、模拟量输入部分: (3)2)、DC设置部分: (3)3)、ADC电源: (4)(3)ADC转换步骤: (4)2、MMI5402的DAC811的介绍: (4)(1)、DAC811简介 (4)(2)其原理图如下: (5)(3)其操作逻辑真值表如下: (5)3、FFT算法简介: (5)四、实验程序功能与结构说明: (6)五、实验流程图 (7)六、实验步骤: (7)1、实验演示: (7)2、实验的调试: (8)七、实验主要程序: (8)1、主函数: (8)2、中断程序: (15)3、异步串口初始化程序 (16)4、AD初始化: (17)七、实验结果: (18)1、SEEDDEC2812单元的D3灯由闪烁变成常暗。
(18)2、时域和频域曲线图: (18)八、实验心得: (19)一、实验目的:1、熟悉CCS集成开发环2、熟悉SEED-DTK2812实验环境3、了解SEED-MMI的系统硬件4、了解DAC811的工作方式5、加深对DFT算法原理和基本性质的理解6、学习用FFT对连续信号和时域信号地频谱分析的方法7、熟悉FFT的算法原理和FFT子程序的算法流程和应用8、了解DSP处理FFT算法的特殊寻址方式二、实验内容:1、DSP的初始化2、AD的初始化3、产生不同幅度民频率的波形4、A/D采样5、DSP之间的UART通讯6、FFT的位倒序程序7、FFT的蝶形运算程序8、求功率谱的程序9、串口发送与接收三、实验所用主要部件结构说明:1、TMS320F2812片内有1个带采样保持电路的12BIT的A/D转换模块(1)、ADC的特点:1)、带S/H的12BIT的ADC2)、模拟量输入范围:0.0V~3.0V3)、转换率:在25MHz的ADC时钟下为80ns4)、16路AD转换通道5)、自动排序功能可以提供一次触发转换16路AD,每次转换能够编程选择16路通道的任何1个6)、排序可以选择2个独立的8通道路排序或者是1个大的16通道排序7)、转换结果表明存储在16个寄存器中,转换结果=4095*(输入的模拟信号-ADCLO)/38)、有多重触发AD转换方式:软件启动、EVA和EVB9)、中断控制方式灵活,可以在每次转换结束或每隔一次转换结束触发中断(2)ADC管脚信号ADC管脚由模拟量输入部分、ADC设置部分和ADC电源三部分构成。
1)、模拟量输入部分:A通道输入:ADCINA0~ADCINA7B通道输入:ADCINB0~ADCINB72)、DC设置部分:ADC电压参考输出(2V):ADCREFPADC电压参考输出(1V):ADCREFMADC外部电流旁路电阴:ADCRESEXT测试管脚下:ADCBGREFINADC模拟地:AVSSREFBGADC模拟电源:AVDDREFBGADC公共地:ADCLO3)、ADC电源:ADC模拟地:VSSA1、VSSA2ADC模拟民源:VDDA1、VDDA2ADC数字地:VSS1ADC数字电源:VDD1(3)ADC转换步骤:1)、初始化DSP系统2)、设置PIE中断矢量表3)、初始化ADC模块4)、将ADC中断的入口地址装入PIE中断矢量表中,开中断5)、软件启动ADC转换6)、等待ADC中断7)、在ADC中断中读取ADC转换结果,软件启动下一次ADC中断2、MMI5402的DAC811的介绍:(1)、DAC811简介DAC811为12BIT,±10V量程,±15V供电的并行D/A转换器。
它内部有2个锁存器。
操作时,先将数据锁存到锁存器中,然后再启动转换寄存器;这样,D/A输出相应的电平。
(2)其原理图如下:(3)其操作逻辑真值表如下:3、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的优越性;FFT算法的输出X(K)为自然顺序,但为了适应原位计算,其输入序列不是按x(n)的自然顺序排序,这种经过M-1次奇偶抽选后的排序为序列的倒序。
因此,在运算之前应先对序列x(n)进行倒序。
倒序的规律就是把顺序数的二进制位倒置,即可得到倒序值。
倒序数是在M位二进制数最高位加一,逢2向右进位。
对于FFT,M位二进制数最高位的权值为N/2,且从左到右二进制位的权值依次为你N/4,N/8,···,2,1。
因此,最高位加一相当于十进制运算J+N/2。
(J表示当前倒序数的十进制数值)。
四、实验程序功能与结构说明:在音频信号数字滤波与FFT分析实验中主要包含以下文件:1、DTK_BPD_AD.c:这是实验的主程序,包含定时器中断程序、AD中断程序,完成与SEED-MMI5402系统的异步通讯。
2、DSP28_Sci.c:包含了串中初始化程序。
3、DSP28_Adc.c:包含了AD初始化。
4、DSP28_Defaultlsr.c:包含了异步串口接收中断服务程序。
5、SRAM.cmd:声明了系统的存贮器配置与程序各段的链接关系。
6、DTK_BPD_FFT.out:DSP上可执行的程序,即实验程序。
7、DTK_BPD_FFT.c:这是实验的主程序,包含了包含定时器中断程序、AD中断程序、FFT参数的初始化,完成与SEED-MMI5402的系统的异步通讯、信号采集与FFT计算。
五、实验流程图六、实验步骤:1、实验演示:在脱机(不接CCS)的情况下,可以首先进行实验的演示。
在实验选项的菜单下,选择FFT实验一项。
先择不使用CCS,确定后,LCD显示屏将显示“程序装载中,请稍侯”,并且用状态条显示程序装载进度,等待装载程序后,SEEDDEC2812单元的D3灯由闪烁变暗。
LCD显示屏将显示“音频信号数字滤波与FFT分析”。
可以看到下面波形:2、实验的调试:1)、将DSP仿真器与计算机连接好:2)、将DSP仿真器的JTAG插关与SEED-DEC2812单元的J1相连接3)、启动计算机,当计算机启动后,打开SEED-DTK BPD的电源。
观察SEEK-DTK_IO单元的+5V、+3.3V、+15V、-15V的电源指示灯是否均亮,若有不亮的,请断开电源,检查电源。
4)、在实验选项的菜单下,选择定时器实验一项,选择使用CCS。
5)、打开CCS,进入CCS的操作环境。
6)、装入DTK_BPD_FFT.wks调试环境。
7)、进行调度,通过Probe Points来观察FFT的结果。
七、实验主要程序:1、主函数:void main(void){/*初始化系统*/InitSysCtrl();/*关中断*/DINT;IER = 0x0000;IFR = 0x0000;/*初始化PIE中断*/InitPieCtrl();/*初始化PIE中断矢量表*/InitPieVectTable();/*初始化SCIA寄存器*/InitSci();//初始化cputimerInitCpuTimers();for(i= 0; i<0x104;i++){uart[i] = 0x5555;uarts[i] = 0x5555;}for(i=0;i<32;i++){sys_statbuff[i]=0;//系统标志buff清0}CommandSave=0;/*设置中断服务程序入口地址*/EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.TXAINT = &SCITXINTA_ISR;PieVectTable.RXAINT = &SCIRXINTA_ISR;PieVectTable.TINT2 = &ISRTimer2;PieVectTable.ADCINT = &ad;EDIS; // This is needed to disable write to EALLOW protected registers///*开中断*/IER |= M_INT9;//SCI中断IER |= M_INT1;//ADC中断EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGMLED1_ON;*LED3=0;/*实验主控程序*/psend = (PuartForDec5416)(&uarts[0]);precieve = (PuartForDec5416)(&uart[0]);padset = (PAdConfig)(&adset[0]);/*通知主机,系统准备好*/psend->Length = FRAMLONGTH;psend->Type = UARTCOMMAND;psend->Data[0] = INITOVER;psend->Mutul = UARTCONT;uart_send();for(;;){if(CommandSave==FFTDATASEND){CommandSave=0;/*不满buffer的数据*/if(datasendlength <= 256){for(i = 0;i<datasendlength;i++){psend->Data[i] = Ad_data[i+sendcount*256];}psend->Length = datasendlength;psend->Type = UARTDATA;psend->Mutul = UARTCONT;uart_send();}else{/*满buffer数据*/for(k = 0; k<256;k++){psend->Data[k] = Ad_data[k+sendcount*256];}psend->Length = 256;psend->Type = UARTDATA;psend->Mutul = UARTMUTL;uart_send();datasendlength= datasendlength - 256;sendcount++;}}uart_s =uart_recive();/* 返回值 0:接受完成*//* 1:数据未准备好*//* 3: 较验出错*/if(uart_s==1){continue;}/*数据较验出错*/if(uart_s == 3){for(i= 0; i<0x104;i++){uart[i] = 0x5555;}/*通知主机程序通讯出错,准备重发*/psend->Length = FRAMLONGTH;psend->Type = UARTCOMMAND;psend->Data[0] = RECIEVEERROR;psend->Mutul = UARTCONT;uart_send();continue;}/*接收完成*/if(uart_s ==0){/*不是命令帧*/if(precieve->Type != UARTCOMMAND){/*无效命令*/psend->Length = FRAMLONGTH;psend->Type = UARTCOMMAND;psend->Data[0] = COMMANDNODO;psend->Mutul = UARTCONT;uart_send();precieve->Type = UARTCOMMAND;continue;}}/*接收从主机的数据*/precieve = (PuartForDec5416)(&uart[0]);switch(precieve->Data[0]){/*FFT设置*/case FFTSET:for(i=0;i<3;i++){adset[i] = precieve->Data[i+1];}/*设置数据发送长度*/datasendlong = padset->SampleLong;datasendlength= 3*datasendlong/2;precieve->Data[0] = 0;break;/*启动AD采样和fft计算*/case FFTSTART:convcount=0;adconvover=0;sendcount=0;convfirstN=1000;/*AD采样率*/switch( padset->SampleRate){case ADSAMPL8K: //0xd //采样率为8kDINT;/*设置CPU*/ConfigCpuTimer(&CpuTimer2, 150, 125);StartCpuTimer2();/*开中断*/IER |= M_INT14;EINT;InitAdc();break;case ADSAMPL44K: // 0x23 //采样率为44kDINT;/*设置CPU*/ConfigCpuTimer(&CpuTimer2, 150, 22);StartCpuTimer2();/*开中断*/IER |= M_INT14;EINT;InitAdc();break;case ADSAMPL96K://0x1d //采样率为96kDINT;/*设置CPU*/ConfigCpuTimer(&CpuTimer2, 150, 10);StartCpuTimer2();/*开中断*/IER |= M_INT14;EINT;InitAdc96k();break;default:break;}for(;;){if (adconvover==1)break;}/*AD采样结束*//*fft转换*//* Initialize FFT module */ switch(datasendlong){case 128:fft128.ipcbptr=ipcb;fft128.init(&fft128);for(i=0;i<datasendlong;i++){ipcb[i] = Ad_data[i];Ad_data[i]=(Ad_data[i]>>4)-0x555;//偏移量1v。