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傅里叶变换的更多相关文章

  1. FFT教你做乘法(FFT傅里叶变换)

    题目来源:https://biancheng.love/contest/41/problem/C/index FFT教你做乘法 题目描述 给定两个8进制正整数A和B(A和B均小于10000位),请利用 ...

  2. STM32F103VET6 ADC采集64点做FFT变换

    http://www.stmcu.org/module/forum/thread-598459-1-11.html http://bbs.21ic.com/icview-589756-1-1.html ...

  3. FFT【快速傅里叶变换】FWT【快速沃尔什变换】

    实在是 美丽的数学啊 关于傅里叶变换的博客 讲的很细致 图片非常易于理解http://blog.jobbole.com/70549/ 大概能明白傅里叶变换是干吗的了 但是还是不能明白为什么用傅里叶变换 ...

  4. 快速傅里叶变换(FFT)相关内容汇总

    (原稿:https://paste.ubuntu.com/p/yJNsn3xPt8/) 快速傅里叶变换,是求两个多项式卷积的算法,其时间复杂度为$O(n\log n)$,优于普通卷积求法,且根据有关证 ...

  5. python做傅里叶变换

    傅里叶变换(fft) 法国科学家傅里叶提出,任何一条周期曲线,无论多么跳跃或不规则,都能表示成一组光滑正弦曲线叠加之和.傅里叶变换即是把一条不规则的曲线拆解成一组光滑正弦曲线的过程. 傅里叶变换的目的 ...

  6. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  7. 快速傅里叶变换(FFT)学习笔记(其一)

    再探快速傅里叶变换(FFT)学习笔记(其一) 目录 再探快速傅里叶变换(FFT)学习笔记(其一) 写在前面 为什么写这篇博客 一些约定 前置知识 多项式卷积 多项式的系数表达式和点值表达式 单位根及其 ...

  8. 【数学】快速傅里叶变换(FFT)

    快速傅里叶变换(FFT) FFT 是之前学的,现在过了比较久的时间,终于打算在回顾的时候系统地整理一篇笔记,有写错的部分请指出来啊 qwq. 卷积 卷积.旋积或褶积(英语:Convolution)是通 ...

  9. 快速傅里叶变换(FFT)随笔

    终于学会了FFT,水一篇随笔记录一下 前置知识网上一大堆,这里就不多赘述了,直接切入正题 01 介绍FFT 这里仅指出FFT在竞赛中的一般应用,即优化多项式乘法 一般情况下,计算两个规模为$n$的多项 ...

随机推荐

  1. Django的模版引擎与模版使用

    Django的模版引擎与模版使用 模版引擎是模版响应的后端.模版指的是HTML.css,js等相关的文件.模版引擎是将这些表示层文件与数据相整合在一起,然后将整合后的数据给到响应类型判断采用一次性响应 ...

  2. jQuery .attr()和.removeAttr()方法操作元素属性示例

    今天主要和大家一起分享一下如何使用jQuery的.attr()和.removeAttr()方法读取,添加,修改,删除元素的属性.大家在平时的Web页面制作中都有碰到如何动态的获取元素的属性和属性值,或 ...

  3. PAT——1033. 旧键盘打字

    旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及坏掉的那些键,打出的结果文字会是怎样? 输入格式: 输入在2行中分别给出坏掉的那些键.以及应该输入的文 ...

  4. flink Window的Timestamps/Watermarks和allowedLateness的区别

    Watermartks是通过additional的时间戳来控制窗口激活的时间,allowedLateness来控制窗口的销毁时间.   注: 因为此特性包括官方文档在1.3-1.5版本均未做改变,所以 ...

  5. 多线程系列 - 基础篇01 - 线程基本概念 & 线程优先级 & 守护线程 60%

    1.什么是线程 将线程理解为轻量级进程,它与进程的最大的区别是: 多个线程共享一个进程资源: 对于OS的许多资源的分配和管理(如内存)通常都是进程级别的,线程只是os调度的最小单位: 相对于进程来说更 ...

  6. form组件-字段

    Form类 创建Form类时,主要涉及到 [字段] 和 [插件],字段用于对用户请求数据的验证,插件用于自动生成HTML 1.Django内置字段如下: Field required=True, 是否 ...

  7. [ERROR] Can't find error-message file '/data/mysql/share/errmsg.sys'. Check error-message file location and 'lc-messages-dir' configuration directive.

    1. MySQL5.7.21启动时报错: [ERROR] Can't find error-message file '/data/mysql/3307/share/errmsg.sys'. Chec ...

  8. 100-Days-Of-ML-Code 评注版(Day 3)

    Day3_Multiple_Linear_Regression(多元线性回归) 本文引用自 Multiple_Linear_Regression, 对其中内容进行了评注与补充说明. 回归分析是一种预测 ...

  9. 树莓派3B+学习笔记:5、安装vim

    以下操作使用root账户登陆. 1.在终端中输入 apt-get install vim 输入“y”,回车: 2.等一下,安装完成: 3.用vim新建一个文本文件测试一下,在终端重输入 vim tes ...

  10. nexus3使用docker运行/创建docker私有仓库/maven私有仓库

    version: '3.2' services: nexus3: container_name: nexus3 hostname: nexus3 image: sonatype/nexus3:3.14 ...