DSP28335做FFT傅里叶变换
1. 看了一下例程,居然没有FFT的例程,难道这个DSP28335不能做FFT吗?对了C2000系列是有C2000 ware这个库的。方便很多,不过目前不确定在C5000上运行的FFT能直接迁移到DSP28335上行不?测试了一下,是可以的,因为都是用的math.h,下面的一些正弦函数基本一样的

2. 硬件简介,其中DSP28335和TLV320AIC23B之间使用I2C接口进行寄存器配置,通过MCBSP进行数据传输。

3. 实际的硬件连接,左边的接耳机,右边的接电脑的音频输出(电脑的耳机输出)。

4. 相关代码,通过中断的方式,TLV320AIC23B,每次采集128个点,然后对这128个点,进行傅里叶变化。同时,DSP28335采集电脑的声音,然后再播放出来。
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include <math.h> #define PI 3.1415926
#define SAMPLENUMBER 128
/****************端口宏定义*****************/
#define LuYin GpioDataRegs.GPADAT.bit.GPIO12
#define LuYin_ST GpioDataRegs.GPADAT.bit.GPIO13
#define BoYin GpioDataRegs.GPADAT.bit.GPIO14 //标志位,用来确定是采集数据还是进行FFT
unsigned char fft_or_sample_data = ;
//采集到了第几个数据,设定一个全局变量,不过还是先检测一下FFT是否能使用吧
unsigned int sample_data_index = ;
int INPUT[SAMPLENUMBER],DATA[SAMPLENUMBER];
float fWaveR[SAMPLENUMBER],fWaveI[SAMPLENUMBER],w[SAMPLENUMBER];
float sin_tab[SAMPLENUMBER],cos_tab[SAMPLENUMBER]; void InitForFFT();
void MakeWave();
void test_fft(void);
void I2CA_Init(void);
Uint16 AIC23Write(int Address,int Data);
void Delay(int time);
void delay();
interrupt void ISRMcbspSend(); void main(void)
{
InitSysCtrl();
// InitXintf16Gpio(); //zq
InitMcbspaGpio(); //zq
InitI2CGpio();
// AUDIOEN = 0;
// Disable CPU interrupts
DINT;
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
I2CA_Init();
// Clear Counters
// PassCount = 0;
// FailCount = 0;
AIC23Write(0x00,0x17); //AIC23Write(0x00,0x00);
Delay();
AIC23Write(0x02,0x17); //AIC23Write(0x02,0x00);
Delay();
AIC23Write(0x04,0x7f);
Delay();
AIC23Write(0x06,0x7f);
Delay();
AIC23Write(0x08,0x10); //AIC23Write(0x08,0x14);
Delay();
AIC23Write(0x0A,0x05); //AIC23Write(0x0A,0x00);
Delay();
AIC23Write(0x0C,0x00);
Delay();
AIC23Write(0x0E,0x53); //AIC23Write(0x0E,0x43);
Delay();
AIC23Write(0x10,0x2f); //AIC23Write(0x10,0x23);
Delay();
AIC23Write(0x12,0x01);
Delay(); //AIC23Init InitMcbspa(); // Initalize the Mcbsp-A EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.MRINTA = &ISRMcbspSend;
EDIS; // This is needed to disable write to EALLOW protected registers PieCtrlRegs.PIECTRL.bit.ENPIE = ; // Enable the PIE block
PieCtrlRegs.PIEIER6.bit.INTx5=; // Enable PIE Group 6, INT 5
IER |= M_INT6; // Enable CPU INT6 EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
test_fft();
} // end of main void I2CA_Init(void)
{
// Initialize I2C
I2caRegs.I2CSAR = 0x001A; // Slave address - EEPROM control code #if (CPU_FRQ_150MHZ) // Default - For 150MHz SYSCLKOUT
I2caRegs.I2CPSC.all = ; // Prescaler - need 7-12 Mhz on module clk (150/15 = 10MHz)
#endif
#if (CPU_FRQ_100MHZ) // For 100 MHz SYSCLKOUT
I2caRegs.I2CPSC.all = ; // Prescaler - need 7-12 Mhz on module clk (100/10 = 10MHz)
#endif I2caRegs.I2CCLKL = ; // NOTE: must be non zero
I2caRegs.I2CCLKH = ; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts // I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
I2caRegs.I2CMDR.all = 0x0420; // Take I2C out of reset //zq
// Stop I2C when suspended I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT, return;
} Uint16 AIC23Write(int Address,int Data)
{ if (I2caRegs.I2CMDR.bit.STP == )
{
return I2C_STP_NOT_READY_ERROR;
} // Setup slave address
I2caRegs.I2CSAR = 0x1A; // Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == )
{
return I2C_BUS_BUSY_ERROR;
} // Setup number of bytes to send
// MsgBuffer + Address
I2caRegs.I2CCNT = ;
I2caRegs.I2CDXR = Address;
I2caRegs.I2CDXR = Data;
// Send start as master transmitter
I2caRegs.I2CMDR.all = 0x6E20;
return I2C_SUCCESS;
} void Delay(int time)
{
int i,j,k=;
for(i=;i<time;i++)
for(j=;j<;j++)
k++;
} void delay(Uint32 k)
{
while(k--);
} interrupt void ISRMcbspSend(void)
{
int temp1,temp2;
temp1=McbspaRegs.DRR1.all;
temp2=McbspaRegs.DRR2.all;
McbspaRegs.DXR1.all = temp1; //放音
McbspaRegs.DXR2.all = temp2;
PieCtrlRegs.PIEACK.all = 0x0020; if(fft_or_sample_data == )
{
//保存数据
INPUT[sample_data_index++] = (temp1 << ) + temp2;
if(sample_data_index == SAMPLENUMBER)
{
fft_or_sample_data = ;
}
}
// PieCtrlRegs.PIEIFR6.bit.INTx5 = 0;
// ERTM;
} void test_fft(void)
{
unsigned int i = ;
InitForFFT();
// MakeWave();
while()
{
if(fft_or_sample_data == ) //假如标志位是1,那么进行FFT运算
{
for ( i=;i<SAMPLENUMBER;i++ )
{
fWaveR[i]=INPUT[i];
fWaveI[i]=0.0f;
w[i]=0.0f;
}
FFT(fWaveR,fWaveI);
for ( i=;i<SAMPLENUMBER;i++ )
{
DATA[i]=w[i];
}
}
else
{
Delay();
}
}
} void FFT(float dataR[SAMPLENUMBER],float dataI[SAMPLENUMBER])
{
int x0,x1,x2,x3,x4,x5,x6,xx;
int i,j,k,b,p,L;
float TR,TI,temp; /********** following code invert sequence ************/
for ( i=;i<SAMPLENUMBER;i++ )
{
x0=x1=x2=x3=x4=x5=x6=;
x0=i&0x01; x1=(i/)&0x01; x2=(i/)&0x01; x3=(i/)&0x01;x4=(i/)&0x01; x5=(i/)&0x01; x6=(i/)&0x01;
xx=x0*+x1*+x2*+x3*+x4*+x5*+x6;
dataI[xx]=dataR[i];
}
for ( i=;i<SAMPLENUMBER;i++ )
{
dataR[i]=dataI[i]; dataI[i]=;
} /************** following code FFT *******************/
for ( L=;L<=;L++ )
{ /* for(1) */
b=; i=L-;
while ( i> )
{
b=b*; i--;
} /* b= 2^(L-1) */
for ( j=;j<=b-;j++ ) /* for (2) */
{
p=; i=-L;
while ( i> ) /* p=pow(2,7-L)*j; */
{
p=p*; i--;
}
p=p*j;
for ( k=j;k<;k=k+*b ) /* for (3) */
{
TR=dataR[k]; TI=dataI[k]; temp=dataR[k+b];
dataR[k]=dataR[k]+dataR[k+b]*cos_tab[p]+dataI[k+b]*sin_tab[p];
dataI[k]=dataI[k]-dataR[k+b]*sin_tab[p]+dataI[k+b]*cos_tab[p];
dataR[k+b]=TR-dataR[k+b]*cos_tab[p]-dataI[k+b]*sin_tab[p];
dataI[k+b]=TI+temp*sin_tab[p]-dataI[k+b]*cos_tab[p];
} /* END for (3) */
} /* END for (2) */
} /* END for (1) */
for ( i=;i<SAMPLENUMBER/;i++ )
{
w[i]=sqrt(dataR[i]*dataR[i]+dataI[i]*dataI[i]);
}
} /* END FFT */ void InitForFFT()
{
int i; for ( i=;i<SAMPLENUMBER;i++ )
{
sin_tab[i]=sin(PI**i/SAMPLENUMBER);
cos_tab[i]=cos(PI**i/SAMPLENUMBER);
}
} void MakeWave()
{
int i; for ( i=;i<SAMPLENUMBER;i++ )
{
INPUT[i]=sin(PI**i/SAMPLENUMBER*)*;
}
}
5. 先检查FFT是否可用,按照下面的修改代码,可以单纯的测试FFT功能
void test_fft(void)
{
unsigned int i = ;
InitForFFT();
MakeWave();
while()
{
if(fft_or_sample_data == 1) //假如标志位是1,那么进行FFT运算
{
for ( i=;i<SAMPLENUMBER;i++ )
{
fWaveR[i]=INPUT[i];
fWaveI[i]=0.0f;
w[i]=0.0f;
}
FFT(fWaveR,fWaveI);
for ( i=;i<SAMPLENUMBER;i++ )
{
DATA[i]=w[i];
}
}
else
{
Delay(1);
}
}
}
6. 观察一下FFT输出的结构是否OK

配置参数

7. 查看输出结果

8. 不过如果相对声音进行FFT运算的话,实际上声音的变化非常快,所以上图的FFT结果,会一直变化的。而且由于声音的频率变化非常快,所以肉眼观察,基本难度很大。
DSP28335做FFT傅里叶变换的更多相关文章
- FFT教你做乘法(FFT傅里叶变换)
题目来源:https://biancheng.love/contest/41/problem/C/index FFT教你做乘法 题目描述 给定两个8进制正整数A和B(A和B均小于10000位),请利用 ...
- STM32F103VET6 ADC采集64点做FFT变换
http://www.stmcu.org/module/forum/thread-598459-1-11.html http://bbs.21ic.com/icview-589756-1-1.html ...
- FFT【快速傅里叶变换】FWT【快速沃尔什变换】
实在是 美丽的数学啊 关于傅里叶变换的博客 讲的很细致 图片非常易于理解http://blog.jobbole.com/70549/ 大概能明白傅里叶变换是干吗的了 但是还是不能明白为什么用傅里叶变换 ...
- 快速傅里叶变换(FFT)相关内容汇总
(原稿:https://paste.ubuntu.com/p/yJNsn3xPt8/) 快速傅里叶变换,是求两个多项式卷积的算法,其时间复杂度为$O(n\log n)$,优于普通卷积求法,且根据有关证 ...
- python做傅里叶变换
傅里叶变换(fft) 法国科学家傅里叶提出,任何一条周期曲线,无论多么跳跃或不规则,都能表示成一组光滑正弦曲线叠加之和.傅里叶变换即是把一条不规则的曲线拆解成一组光滑正弦曲线的过程. 傅里叶变换的目的 ...
- 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)
再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...
- 快速傅里叶变换(FFT)学习笔记(其一)
再探快速傅里叶变换(FFT)学习笔记(其一) 目录 再探快速傅里叶变换(FFT)学习笔记(其一) 写在前面 为什么写这篇博客 一些约定 前置知识 多项式卷积 多项式的系数表达式和点值表达式 单位根及其 ...
- 【数学】快速傅里叶变换(FFT)
快速傅里叶变换(FFT) FFT 是之前学的,现在过了比较久的时间,终于打算在回顾的时候系统地整理一篇笔记,有写错的部分请指出来啊 qwq. 卷积 卷积.旋积或褶积(英语:Convolution)是通 ...
- 快速傅里叶变换(FFT)随笔
终于学会了FFT,水一篇随笔记录一下 前置知识网上一大堆,这里就不多赘述了,直接切入正题 01 介绍FFT 这里仅指出FFT在竞赛中的一般应用,即优化多项式乘法 一般情况下,计算两个规模为$n$的多项 ...
随机推荐
- 数论——算数基本定理 - HDU 4497 GCD and LCM
GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total ...
- 【CSS3】自定义滚动条样式 -webkit-scrollbar
好文推荐:http://m.blog.csdn.net/article/details?id=40398177 http://www.xuanfengge.com/css3-webkit-scroll ...
- Mac OS X文件系统的附加属性@如何彻底删除
有时候在 Mac 系统下读写 NTFS 分区时,会发现一些文件不能打开. 显示错误为: 项目“XXX”已被 OS X 使用,不能打开. 如果再终端 ls -al 命令一下就可以看到: -rwxr-xr ...
- 一种基于openflow的虚拟化层软件flowvisor的API测试
注明:本文并不对openflow进行分析,本人也是略略知道这个概念,对flowvisor也只是对其API有所测试,更深的源码并未涉及,只是希望该文能对以后的flowvisor研究者提供些许帮助. 一: ...
- spring框架中beans.xml文件报错XmlBeanDefinitionStoreException
第一次构建spring,实现简单的注入方式,就发生了beans.xml文件报错,报错信息如下图 org.springframework.beans.factory.xml.XmlBeanDefinit ...
- HomeKit 开发指南(中文版)
转载自cocoachina 本文由CocoaChina翻译组成员iBenjamin_Go和浅夏@旧时光翻译自苹果开发文档:HomeKit Developer Guide,敬请勘误. 本文档内容包括 第 ...
- Android 异步开发之 AsyncQueryHandler 批量添加联系人
AsyncQueryHandler: 官方解释是一个异步帮助类(A helper class to help make handling asynchronous ContentResolver qu ...
- 404 Note Found 队-Alpha10
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- ASP.NET Core 中的 WebSocket 支持(转自MSDN)
本文介绍 ASP.NET Core 中 WebSocket 的入门方法. WebSocket (RFC 6455) 是一个协议,支持通过 TCP 连接建立持久的双向信道. 它用于从快速实时通信中获益的 ...
- 修改eclipse中文件打开默认方式
Window--->prefrence---->Editors----->FileAssociation 选择文件后缀,如果没有就添加,然后在上添加,删除,设置默认打开方式.