搜索
bottom↓
回复: 51

采用TMS320F2812进行FFT变换

[复制链接]

出0入0汤圆

发表于 2010-7-1 17:06:43 | 显示全部楼层 |阅读模式
FFT结果的物理意义 : 可以参考本论坛链接:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3944963&bbs_page_no=1&search_mode=1&search_text=FFT&bbs_id=9999


开发板采用ICETEK-F2812-A
FFT计算采用TI的FFT程序,信号发生器产生正弦波信号,输入ACD0,AD采样率为3KHz,
注意:2812输入的电压:0-3V,信号发生器的正弦波信号应有一个整的offset。

2812的主程序:

实际的FFT运算程序:

#include "DSP281x_Device.h"     // DSP281x Headerfile Include File
#include "DSP281x_Examples.h"   // DSP281x Examples Include File

/* for test fft */
#include "fft.h"


// Prototype statements for functions found within this file.
interrupt void adc_isr(void);

// Global variables used in this example:
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 Voltage1[1024];
Uint16 Voltage2[1024];



#define N 1024                         //FFT Length
#pragma DATA_SECTION(ipcb, "FFTipcb");
#pragma DATA_SECTION(mag,"FFTmag");
RFFT32 fft=RFFT32_1024P_DEFAULTS;
long ipcb[N+2];                        //In place computation buffer
long mag[N/2+1];                        //Magnitude buffer

//const long win[N/2]=HAMMING128;        //Window coefficient array  

RFFT32_ACQ acq=FFTRACQ_DEFAULTS;    //Instance the module




main()
{
   
    int i;

   InitSysCtrl();//初始化cpu
   
   DINT;//关中断

   InitPieCtrl();//初始化pie寄存器


/* Initialize acquisition module                    */
   acq.buffptr=ipcb;
   acq.tempptr=ipcb;
   acq.size=N;
   acq.count=N;
   acq.acqflag=1;

/* Initialize FFT module                            */
   fft.ipcbptr=ipcb;
   fft.magptr=mag;
   fft.init(&fft);  

   
   IER = 0x0000;//禁止所有的中断
   IFR = 0x0000;


   InitPieVectTable();//初始化pie中断向量表
     
// 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
   AdcRegs.ADCTRL1.bit.RESET = 1;        // Reset the ADC module
    asm(" RPT #10 || NOP");                // Must wait 12-cycles (worst-case) for ADC reset to take effect
   AdcRegs.ADCTRL3.all = 0x00C8;        // first power-up ref and bandgap circuits
   
   AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3;    // Power up bandgap/reference circuitry

   AdcRegs.ADCTRL3.bit.ADCPWDN = 1;        // Power up rest of ADC

// Enable ADCINT in PIE
   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 = 1;
   
// Configure ADC
   AdcRegs.ADCMAXCONV.all = 0x0001;       // Setup 2 conv's on SEQ1
   AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA3 as 1st SEQ1 conv.
   AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup ADCINA2 as 2nd SEQ1 conv.
   AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1;  // Enable EVASOC to start SEQ1
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)

// Configure EVA
// Assumes EVA Clock is already enabled in InitSysCtrl();
   EvaRegs.T1CMPR = 0x0080;               // Setup T1 compare value
   EvaRegs.T1PR = 0x61a8;                 // Setup period register
   EvaRegs.GPTCONA.bit.T1TOADC = 1;       // Enable EVASOC in EVA
   EvaRegs.T1CON.all = 0x1042;            // Enable timer 1 compare (upcount mode)










// Wait for ADC interrupt
   while(1)
   {
      //LoopCount++;
      if (acq.acqflag==0)     // If the samples are acquired     
      {  
   
        DINT;
        //RFFT32_brev(ipcb,ipcb,N);
        //RFFT32_brev(ipcb,ipcb,N);  // Input samples in Real Part
      
         fft.calc(&fft);
         fft.split(&fft);
         fft.mag(&fft);
         for(i=0;i<N;i++)
         {
               
            mag=sqrt(mag);
         }
         acq.acqflag=1;      // Enable the next acquisition     
         EINT;
      }
   }

}


interrupt void  adc_isr(void)
{

  Voltage1[ConversionCount] = AdcRegs.ADCRESULT0>>4;

  acq.input=((unsigned long)Voltage1[ConversionCount])<<16;
  acq.update(&acq);


// ipcb[ConversionCount]=((unsigned long)Voltage1[ConversionCount])<<16;

  Voltage2[ConversionCount] = AdcRegs.ADCRESULT1 >>4;

  // If 40 conversions have been logged, start over
  if(ConversionCount == 1023)
  {
     ConversionCount = 0;  

    // acq.acqflag=0;
  }
  else ConversionCount++;

  // Reinitialize for next ADC sequence
  AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
  AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

  return;
}



/*
//###########################################################################
//
// 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 <base>\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 <base>\DSP281x_headers\cmd to the
   library search path under project->build options, linker tab,
   library search path (-i).
/*========================================================= */
-l rts2800.lib
-w
-stack 400h
-heap 100
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
   //RAMM0      : origin = 0x3f6000, length = 0x001000
   BEGIN      : origin = 0x3F8000, length = 0x000002
   /*BEGIN      : origin = 0x3F7FF6, length = 0x000002*/            
   PRAMH0     : origin = 0x3f8002, length = 0x000FFE


   PRAMH1     : origin = 0x80000, length = 0x0FFFF        /* 64K external RAM */
   RESET       : origin = 0x3FFFC0, length = 0x000002     /* part of boot ROM (MP/MCn=0) or XINTF zone 7 (MP/MCn=1) */
   VECTORS     : origin = 0x3FFFC2, length = 0x00003E     /* part of boot ROM (MP/MCn=0) or XINTF zone 7 (MP/MCn=1) */

         
PAGE 1 :


   /* For this example, H0 is split between PAGE 0 and PAGE 1 */
   L0L1RAM (RW) : origin = 0x008000, length = 0x2000
   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          : > PRAMH0,      PAGE = 0
   .reset           : > RESET,       PAGE = 0, TYPE = DSECT /* not used, */
   
   
   FFTtf    >    PRAMH0,      PAGE = 0
   DLOG         >    PRAMH0,     PAGE =    0
   FFTipcb    ALIGN(2048)  : { } >    PRAMH1 PAGE 0  
   FFTmag   >    PRAMH1     PAGE 0
   SINTBL    : > L0L1RAM, PAGE =    1   
   
              
   .stack           : > RAMM1,       PAGE = 1
   .ebss            : > DRAMH0,      PAGE = 1
   .econst          : > DRAMH0,      PAGE = 1      
   .esysmem         : > DRAMH0,      PAGE = 1
   .const           : > DRAMH0,      PAGE = 1      
   .sysmem          : > DRAMH0,      PAGE = 1
   .cio             : > DRAMH0,      PAGE = 1

     
}




FFTipcb, FFTmag 的配置必须注意。
aca.updata
可以把ipcb 输入数据与输出数据定义为同一数据,来节省内存



在开始FFT计算时需要
DINT 屏蔽A/D采集中断,结束FFT计算后EINT,以保证
再没有DINT A/D采集时,的截图:A/D采集不连续,

(原文件名:FFT.jpg)
输入信号正弦Vpp 500mV,直流偏置500mV。此时输入的信号:0.5+0.5sin(2*pi*50*t)V

此时,ADC0输入的波形:2812ADC 为12位

(原文件名:FFT.jpg)

FFT的图形:对ADC直接FFT变换:数据演算:
FFT的magtude为357578 变化为电压值 357578/(n/2)/4095*3=0.5115V  ,n=1024

(原文件名:FFT.jpg)


调用2812的FFT子程序进行变换: 数据验算 mag 格式为Q30格式,mag=sqrt(0.00726813)*3*2=0.51152V
f=17*3000/1024=49.8Hz
Ti的FFT程序已经考虑到定点数的溢出问题,在每级的缩放系数为2,所以不用再除以N了,

(原文件名:FFT.jpg)
最终的计算结果合实际值有一点差别。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入42汤圆

发表于 2010-7-1 17:14:20 | 显示全部楼层
很好,mark;就是2812有点贵。

出0入0汤圆

 楼主| 发表于 2010-7-1 17:15:34 | 显示全部楼层
现在的2812还要500元,没有买,还得等一等。

出0入0汤圆

发表于 2010-7-1 17:24:07 | 显示全部楼层
2812 最低时才80一片,现在居然500。

其实,仔细算算做项目也不在乎那几个钱,就怕缺货。

观望中。

出0入0汤圆

发表于 2010-7-1 18:09:11 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-9 08:37:36 | 显示全部楼层
回复【2楼】greenwoods
-----------------------------------------------------------------------

请教一下,我用了你的程序做实验,FFT.H用的是TI自带的那个吗?  还要不要添加什么文件?
我的开发板和你一样的

链接的时候有错误,如下,不知道是什么原因?




[Linking...] "C:\CCStudio_v3.3\C2000\cgtools\bin\cl2000" -@"Debug.lkf"
<Linking>

undefined                        first referenced
symbol                              in file
---------                        ----------------
_CFFT32_calc                     C:\CCStudio_v3.3\MyProjects\fft_icetek\Debug\ADC.obj
_RFFT32_split                    C:\CCStudio_v3.3\MyProjects\fft_icetek\Debug\ADC.obj
_RFFT32_acq                      C:\CCStudio_v3.3\MyProjects\fft_icetek\Debug\ADC.obj
_RFFT32_mag                      C:\CCStudio_v3.3\MyProjects\fft_icetek\Debug\ADC.obj
_CFFT32_init                     C:\CCStudio_v3.3\MyProjects\fft_icetek\Debug\ADC.obj
_RFFT32_win                      C:\CCStudio_v3.3\MyProjects\fft_icetek\Debug\ADC.obj
>>   error: symbol referencing errors - './Debug/adc.out' not built

>> Compilation failure

Build Complete,
  2 Errors, 0 Warnings, 0 Remarks.

出0入0汤圆

发表于 2010-7-9 10:30:24 | 显示全部楼层
没有目标代码,需要加进 fft库。

出0入0汤圆

发表于 2010-7-10 11:01:11 | 显示全部楼层
谢谢楼上的指导,可以运行了

出0入0汤圆

发表于 2010-7-16 13:58:01 | 显示全部楼层
楼上的兄弟们,我也是按照楼主那样做的,现在就是不知道mag[]出来的数据时什么格式?楼主的公式:  数据验算 mag 格式为Q30格式,mag=sqrt(0.00726813)*3*2=0.51152V 应该全部是这样的吧: mag=sqrt(0.00726813)*3K/512=sqrt(0.00726813)*3*2=0.51152V ,不知道我这样验算对不???我用这个公式算出来的不对应。希望楼上的兄弟们帮忙啊!小弟先谢谢大家了~

出0入0汤圆

发表于 2010-7-17 09:02:20 | 显示全部楼层
我也不清楚 楼主最后一步用FFT子程序到底是怎么算的,图形也显示的不对,怎么看自己的MAG格式是多少,在图形的设置选项怎么设置

mag=sqrt(0.00726813)*3*2=0.51152V ,这个式子也不理解




(原文件名:1.jpg)

出0入0汤圆

发表于 2010-7-21 09:40:55 | 显示全部楼层
问下LZ有没有继续做下去,做相位、谐波什么的,我用一些插值算法校正出来的结果中,相位还是跟输入差的太多

出0入0汤圆

发表于 2010-8-5 14:09:54 | 显示全部楼层
回复【2楼】greenwoods
-----------------------------------------------------------------------

greenwoods
可以的话联系我一下,谢谢!
QQ264501976

出0入0汤圆

发表于 2010-8-6 00:31:33 | 显示全部楼层
楼主现身,,,qq 157298746 加我??

出0入0汤圆

发表于 2010-8-6 04:29:51 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-30 19:53:38 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-8 09:26:40 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-3-22 12:12:55 | 显示全部楼层
标记 学习FFT 谢谢分享

出0入0汤圆

发表于 2011-3-22 15:32:13 | 显示全部楼层
哈,最近弄到几片2812,改天试试。

出0入0汤圆

发表于 2011-4-4 08:50:36 | 显示全部楼层
请问各位师兄师姐们 FFt库函数是怎么加载到F2812里的?小弟正要用 亟待你们的帮助啊

出0入0汤圆

发表于 2011-4-20 21:21:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-20 22:17:21 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-4-20 23:01:03 | 显示全部楼层

2812 + FFT 库用于产品中 (原文件名:123123123.JPG)

出0入0汤圆

发表于 2011-4-20 23:13:18 | 显示全部楼层
mark,DSP,FFT

出0入0汤圆

发表于 2011-5-3 23:04:29 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-30 16:54:04 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-3 16:34:30 | 显示全部楼层
MARK.

出0入0汤圆

发表于 2011-6-19 10:23:29 | 显示全部楼层
回复【楼主位】greenwoods  
-----------------------------------------------------------------------

不错!留着待用

出0入0汤圆

发表于 2011-9-4 11:52:07 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-28 08:05:10 | 显示全部楼层
好的文章,收藏了~

出0入0汤圆

发表于 2011-10-12 10:25:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-12 17:25:33 | 显示全部楼层
太好的东西了

出0入0汤圆

发表于 2011-10-15 17:29:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-16 14:57:47 | 显示全部楼层
回复【21楼】lylatyou 张伯伦
-----------------------------------------------------------------------

哇!用的这么爽!

出0入0汤圆

发表于 2011-12-12 22:58:15 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-8 10:53:23 | 显示全部楼层
请问,你们知道2812计算一周波64点的FFT变换需要耗时多少吗?
谢谢

出0入0汤圆

发表于 2012-3-10 18:51:20 | 显示全部楼层
mark fft

出0入0汤圆

发表于 2012-7-21 10:36:37 | 显示全部楼层
正在学习急需啊

出0入0汤圆

发表于 2012-7-27 14:46:11 | 显示全部楼层
给我一片ROM,外加数据选择器,我能用数字序列实现FFT。

出0入0汤圆

发表于 2012-8-29 17:06:30 | 显示全部楼层
学习。。。。。。

出0入0汤圆

发表于 2012-11-2 16:08:47 | 显示全部楼层
楼主能否吧整个2812的工程传上来,谢谢

出0入0汤圆

发表于 2012-11-5 14:56:19 | 显示全部楼层
楼主,能否吧你的工程传上来,这段时间,正好,想用2812做一下FFT,在TI的官网上也没有找到FFT的软件包

出0入0汤圆

 楼主| 发表于 2012-11-5 15:44:32 | 显示全部楼层
自己试一试吧,不确定是不是原来的文件,只有原来的开发板A/D采样工程文件:在此基础上修改,外加TI 的FFT程序。仔细看看TI的FFT程序说明。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-11-9 22:43:44 | 显示全部楼层
很好的资料,必须mark.

出0入0汤圆

发表于 2013-4-19 15:07:44 | 显示全部楼层
正在学习,mark一下,谢谢!

出0入0汤圆

发表于 2013-7-18 13:16:01 | 显示全部楼层
greenwoods 发表于 2012-11-5 15:44
自己试一试吧,不确定是不是原来的文件,只有原来的开发板A/D采样工程文件:在此基础上修改,外加TI 的FFT ...

LZ热心人,感谢分享!

出0入0汤圆

发表于 2013-9-7 23:56:56 | 显示全部楼层
朋友,你好!我看了你关于“采用TMS320F2812进行FFT变换” 的帖子,下载了附件,在ccs3.3上运行,结果编译时出错了,好像是缺少文件,想能和你探讨下,希望得到你的回复,谢谢!  可以加我qq:407043680

出0入0汤圆

发表于 2014-8-18 13:40:17 | 显示全部楼层
不错,学习一下

出0入0汤圆

发表于 2015-6-22 09:51:53 | 显示全部楼层
楼主你好,我想问下怎么设置2812的adc的采样率,在程序的哪里可以设置,急求,谢谢

出0入0汤圆

发表于 2016-9-5 13:59:44 | 显示全部楼层
fc23fcevff23 发表于 2012-7-27 14:46
给我一片ROM,外加数据选择器,我能用数字序列实现FFT。

怎么实现?有算法吗?

出0入0汤圆

发表于 2019-4-12 10:48:39 | 显示全部楼层
2812 AD不行
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 20:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表