微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 硬件电路设计 > TI模拟硬件电路设计 > 请教关于fft的问题。

请教关于fft的问题。

时间:10-02 整理:3721RD 点击:


各位老师好,我想用2812做一个fft的程序,但不知如何下手,我想向各位请教一下,应该如何利用TI公司自带的fft库函数来实现,我现在把需要计算的小数值存放在外部ram中,不知道应该怎么处理,而且我知道2812是一个定点芯片,对于小数又应当如何处理呢,谢谢各位老师了。

对于小数可以用定标的方法

那我通过的AD转换得到的16位数,如果不转换成小数,能不能直接进行FFT变换呢,如果可以的话,应该怎么实现呢,如果不行,那定标识怎么实现的,我不懂啊。

那我再进行fft变换时,必须得进行定标处理吗,我如果直接转换成小数存在外部ram里,不知道这样做可以吗?

看你的算法决定是否使用小数,数据放在哪都无所谓

我是这么想的,我想把AD采到的数据进行放大,然后进行FFT变换,再将转换后的结果同时缩小相应的倍数,然后显示在液晶上,这样就不用进行格式的转化,不知道这样行不?

很多书上都说用C语言来编写fft算法,速度很慢,是不是我不能使用fft库函数,而要使用汇编编写,然后用C语言调用才可以呢,我不会用汇编来编写2812的程序,那我应该怎么办呢?

各位大侠,我还有一个问题要请教,当我用fft库函数作变换时,我想在ccs的图形显示区观察所得到的频谱图,然而利用fft库函数得到的函数值很多,我不知道应该观察那个函数,以及怎样将该函数数组以图形的形式显示出来,希望各位大侠指点一下,还有上面我所问的问题,都指点一下好吗,谢谢大家了。

参考刘和平的2407dsp C语言开发应用 上面有FFT的算法介绍,不过是用汇编的

可我现在想用TI公司的fft库函数直接完成FFT变换,就不需要再编写函数了,因为时间比较急,所以我只能出此下策了,可是我不会用这个库函数,希望大家指点一下好吗?

最近我都要被fft折磨得快要崩溃了,光看资料实在是看不懂,不知道说的是什么意思,还有就是fft库函数里的那些函数是怎么使用的,我一个也看不懂,因此,我十分恳请EEWORLD的老师们能不吝赐教,不胜感激,谢谢各位了。

网上找的资料,据说调通了。(我没试过)

由于2812时定点运算,sin值得大小不能太小!否则计算结果为零!2812的fft的错误在于fft.init1(),fft.init2()这两个函数没有这函数库里面定义,而是该用fft.init(&fft),而且由于是定点运算,输入的sin值不能太小,要不然计算结果为零!

#include \"DSP281x_Device.h\" // DSP281x Headerfile Include File
#include \"DSP281x_Examples.h\" // DSP281x Examples Include File
#include \"fft.h\"
#include
#define BUF_SIZE 128
#pragma DATA_SECTION(ipcb, \"FFTipcb\"

;
#pragma DATA_SECTION(mag, \"FFTmag\"

;
// Prototype statements for functions found within this file.
// Global variables used in this example:
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 fftflag=0;//FFT转换启动标志:0不启动;1:启动
Uint16 i;
long Voltage1[BUF_SIZE];
long Voltage2[BUF_SIZE];
long ipcb[BUF_SIZE];
RFFT32 fft=RFFT32_128P_DEFAULTS;
//CFFT32 fft=CFFT32_128P_DEFAULTS;
long mag[BUF_SIZE/2+1];
const long win[BUF_SIZE/2]=HANNING128;
int x1;
long k=0;
double j=0.12345;

main()
{
Uint16 i;
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP281x_SysCtrl.c file.
InitSysCtrl();
// For this example, set HSPCLK to SYSCLKOUT / 6 (25Mhz assuming 150Mhz SYSCLKOUT)
EALLOW;
SysCtrlRegs.HISPCP.all = 0x3; // HSPCLK = SYSCLKOUT/6
EDIS;

// Step 2. Initialize GPI
// This example function is found in the DSP281x_Gpio.c file and
// illustrates how to set the GPIO to it\'s default state.
// InitGpio(); // Skipped for this example
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP281x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP281x_DefaultIsr.c.
// This function is found in DSP281x_PieVect.c.
InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
// EALLOW; // This is needed to write to EALLOW protected register
// PieVectTable.ADCINT = &adc_isr;
// EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP281x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
InitAdc(); // For this example, init the ADC
// Step 5. User specific code, enable interrupts:

PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
LoopCount = 0;
ConversionCount = 0;

for(i=0;i {
// Voltage1=(long)1000*sin((2*3.14159*i)/25);
ipcb=(long)10000000*sin((2*3.14159*i)/12);
}

// RFFT32_brev(Voltage1,ipcb,BUF_SIZE);
//initialize FFT module
fft.ipcbptr=ipcb;
fft.magptr=ipcb;//存放幅度
// fft.magptr=ipcb;
// fft.winptr=(long *)win;//加窗
fft.init(&fft);
// fft.win(&fft);
RFFT32_brev(ipcb,ipcb,BUF_SIZE);
// RFFT32_brev(ipcb,ipcb,16);
fft.calc(&fft);
fft.split(&fft);
fft.mag(&fft);
for(i=0;i {
mag=sqrt(mag);
}
}

/*
//###########################################################################
//
// FILE: F2812_EzDSP_RAM_lnk.cmd
//
// TITLE: Linker Command File For F2812 eZdsp examples that run out of RAM
// This linker file assumes the user is booting up in Jump to H0 mode
//
//###########################################################################
//
// Ver | dd mmm yyyy | Who | Description of changes
// =====|=============|======|===============================================
// 1.00| 11 Sep 2003 | L.H. | Changes since previous version (v.58 Alpha)
// | | | Added BEGIN section to the start of H0
// | | | Removed .bss, .const and .sysmem
// | | | These are for a small memory model. All examples
// | | | use the large model.
// | | | Added .esysmem section
// | | | Changed ramfuncs section to load and run from RAM
// | | | (previously this was type DSECT)
// | | | Moved peripheral register files to DSP28_Headers_BIOS.cmd
// | | | and DSP28_Headers_nonBIOS.cmd
// | | | Added CSM_RSVD memory section in FLASHA - this region
// | | | should be programmed with all 0x0000 when using the CSM
// -----|-------------|------|-----------------------------------------------
//###########################################################################
*/
/* ======================================================
// For Code Composer Studio V2.2 and later
// ---------------------------------------
// In addition to this memory linker command file,
// add the header linker command file directly to the project.
// The header linker command file is required to link the
// peripheral structures to the proper locations within
// the memory map.
//
// The header linker files are found in \\DSP281x_Headers\\cmd
//
// For BIOS applications add: DSP281x_Headers_nonBIOS.cmd
// For nonBIOS applications add: DSP281x_Headers_nonBIOS.cmd
========================================================= */
/* ======================================================
// For Code Composer Studio prior to V2.2
// --------------------------------------
// 1) Use one of the following -l statements to include the
// header linker command file in the project. The header linker
// file is required to link the peripheral structures to the proper
// locations within the memory map */
/* Uncomment this line to include file only for non-BIOS applications */
/* -l DSP281x_Headers_nonBIOS.cmd */
/* Uncomment this line to include file only for BIOS applications */
/* -l DSP281x_Headers_BIOS.cmd */
/* 2) In your project add the path to \\DSP281x_headers\\cmd to the
library search path under project->build options, linker tab,
library search path (-i).
/*========================================================= */

MEMORY
{
PAGE 0 :
/* For this example, H0 is split between PAGE 0 and PAGE 1 */
/* BEGIN is used for the \"boot to HO\" bootloader mode */
/* RESET is loaded with the reset vector only if */
/* the boot is from XINTF Zone 7. Otherwise reset vector */
/* is fetched from boot ROM. See .reset section below */

RAMM0 : origin = 0x000000, length = 0x000400
BEGIN : origin = 0x3F8000, length = 0x000002
PRAMH0 : origin = 0x3F8002, length = 0x000FFE
RESET : origin = 0x3FFFC0, length = 0x000002

PAGE 1 :
/* For this example, H0 is split between PAGE 0 and PAGE 1 */
RAMM1 : origin = 0x000400, length = 0x000400
DRAMH0 : origin = 0x3f9000, length = 0x001000
}

SECTIONS
{
/* Setup for \"boot to H0\" mode:
The codestart section (found in DSP28_CodeStartBranch.asm)
re-directs execution to the start of user code.
Place this section at the start of H0 */
codestart : > BEGIN, PAGE = 0
ramfuncs : > PRAMH0 PAGE = 0
.text : > PRAMH0, PAGE = 0
.cinit : > PRAMH0, PAGE = 0
.pinit : > PRAMH0, PAGE = 0
.switch : > RAMM0, PAGE = 0
.reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */
FFTtf > PRAMH0, PAGE = 0
FFTipcb ALIGN(256): {}> DRAMH0, PAGE = 1
FFTmag > DRAMH0, PAGE = 1
.stack : > RAMM1, PAGE = 1
.ebss : > DRAMH0, PAGE = 1
.econst : > DRAMH0, PAGE = 1
.esysmem : > DRAMH0, PAGE = 1
}

上午测试过,没问题。

主程序中:

#define N 128
#pragma DATA_SECTION(ipcb, \"FFTipcb\"

;
#pragma DATA_SECTION(mag, \"FFTmag\"

;
RFFT32 fft=RFFT32_128P_DEFAULTS;
long ipcb[N+2];
long mag[N/2+1];

for(i=0;i<N;i++)
{
ipcb=INDATA*65536;//赋值,128点的采样值
//y=0.25cos(314*t)+0.25cos(314*3*t)/3+0.25cos(314*9*t)/9
}
fft.ipcbptr=ipcb;
fft.magptr=mag;
fft.init(&fft);

RFFT32_brev(ipcb,ipcb,N);
fft.calc(&fft);
fft.split(&fft);
fft.mag(&fft);
for(i=0;i<N;i++)
{
mag=sqrt(mag);
}

在CMD文件中添加\"FFTipcb\"、 \"FFTmag\"空间,方法见TI文档
还要包含fft.h、fft.lib
最好看一下TI提供的FFT的文档,说明的很仔细。

对,只能是Q30或者是Q31

那你给的这段程序怎样才能看出你用的是那种Q格式呢?我不大理解。

我现在是外扩得AD,是16位宽度的,而Q30是32位的,怎样转换才可以呢?

我一直用的54X系列的,我调用的是DSPLIB,优化好了的程序例如FFT,添加#include <displib.h>
#include <tms320.h>就可以调用优化后的程序了

我现在还是不大懂,为何我输入的是1024点,输出的是512点的频谱呢,帮忙解释一下阿。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top