128点FFT算法设计方法

合集下载

DSP2812中的FFT运算

DSP2812中的FFT运算

如上图,首先确认你已经加入上述高亮标志的头文件和库文件。

CMD中应该加入如下指令:int Sampling[128];//FFT输入值128点long result[64];//FFT输出结果,前64次谐波average[128];//多周期平均,此处可省略void FFTfunction( int sampling[],long result[]){ for( m=0;m<128;m++){average[m]=sampling[m];}for( m=0;m<128;m++){ipcb[m] =((long)(average[m])<<19);//转换为合适的FFT输入格式}/* Initialize FFT module */fft.ipcbptr=ipcb;//cal()函数处理数据的起始位置//fft.magptr=mag;fft.magptr=mag;//mag()函数后放置幅值平方数据的起始位置//fft.winptr=(long *)win;fft.init(&fft); //复制旋转因子TFRFFT32_brev(ipcb,ipcb,128);//位倒序处理fft.calc(&fft);//调用64点复数FFT计算,输入数据是Q31格式fft.split(&fft);//劈分64点复数结果,得实数128点FIT计算的真正结果fft.mag(&fft);//得到幅值平方,输出的数据是Q30格式for( m=0;m<64;m++){ result[m]=mag[m]; }}输出结果long result[64]中的数据经过公式转化得到各次谐波真实值,其中3V对应采样最值4096。

FFT-IFFT算法程序

FFT-IFFT算法程序

#include <stdio.h>#include <math.h>#include <stdlib.h>#define N_point 128 //傅里叶点数#define N_level 7 //7级蝶形运算//旋转因子实部extern float wr_re[128]={ 1.00000000, 0.99879546, 0.99518473, 0.98917651, 0.98078528, 0.97003125, 0.95694034, 0.94154407, 0.92387954, 0.90398930, 0.88192127, 0.85772861, 0.83146962, 0.80320754, 0.77301046, 0.74095113, 0.70710679, 0.67155897, 0.63439330, 0.59569932, 0.55557025, 0.51410276, 0.47139675, 0.42755511, 0.38268345, 0.33688987, 0.29028470, 0.24298020, 0.19509035, 0.14673050, 0.09801717, 0.04906770, 0.00000003, -0.04906765, -0.09801711, -0.14673045, -0.19509029, -0.24298015, -0.29028465, -0.33688982, -0.38268340, -0.42755506, -0.47139671, -0.51410271, -0.55557020, -0.59569927, -0.63439325, -0.67155893, -0.70710675, -0.74095110, -0.77301043, -0.80320751, -0.83146959, -0.85772859, -0.88192124, -0.90398927, -0.92387951, -0.94154405, -0.95694032, -0.97003124, -0.98078527, -0.98917650, -0.99518472, -0.99879545, -1.00000000, -0.99879546, -0.99518473, -0.98917652, -0.98078529, -0.97003127, -0.95694035, -0.94154409, -0.92387956, -0.90398932, -0.88192129, -0.85772864, -0.83146965, -0.80320757, -0.77301049, -0.74095117, -0.70710683, -0.67155901, -0.63439334, -0.59569936, -0.55557029, -0.51410281, -0.47139680, -0.42755516, -0.38268350, -0.33688992, -0.29028475, -0.24298025, -0.19509040, -0.14673055, -0.09801722, -0.04906775, -0.00000008, 0.04906759, 0.09801706, 0.14673039, 0.19509024, 0.24298010, 0.29028460, 0.33688977, 0.38268335, 0.42755501, 0.47139666, 0.51410267, 0.55557016, 0.59569923, 0.63439321, 0.67155889, 0.70710671, 0.74095106, 0.77301039, 0.80320747, 0.83146956, 0.85772856, 0.88192122, 0.90398925, 0.92387949, 0.94154403, 0.95694031, 0.97003123, 0.98078526, 0.98917649, 0.99518472, 0.99879545};//旋转因子虚部extern float wr_im[128]={ 0.00000000, 0.04906767, 0.09801714, 0.14673047, 0.19509032, 0.24298018, 0.29028467, 0.33688985, 0.38268343, 0.42755509, 0.47139673, 0.51410274, 0.55557022, 0.59569930, 0.63439328, 0.67155895, 0.70710677, 0.74095112, 0.77301044, 0.80320752, 0.83146960, 0.85772860, 0.88192126, 0.90398928, 0.92387952, 0.94154406, 0.95694033, 0.97003125, 0.98078528, 0.98917651, 0.99518472, 0.99879545, 1.00000000, 0.99879546, 0.99518473, 0.98917651, 0.98078529, 0.97003126, 0.95694034, 0.94154408, 0.92387955, 0.90398931, 0.88192128, 0.85772863, 0.83146963, 0.80320755, 0.77301048, 0.74095115, 0.70710681, 0.67155899, 0.63439332, 0.59569934, 0.55557027, 0.51410278, 0.47139678, 0.42755514, 0.38268348, 0.33688990, 0.29028472, 0.24298023, 0.19509037, 0.14673052, 0.09801719, 0.04906773, 0.00000005, -0.04906762, -0.09801709, -0.14673042, -0.19509027, -0.24298012, -0.29028462, -0.33688980, -0.38268338, -0.42755504, -0.47139668, -0.51410269, -0.55557018, -0.59569925,-0.63439323, -0.67155891, -0.70710673, -0.74095108, -0.77301041, -0.80320749, -0.83146957, -0.85772857, -0.88192123, -0.90398926, -0.92387950, -0.94154404, -0.95694031, -0.97003123, -0.98078527, -0.98917650, -0.99518472, -0.99879545, -1.00000000, -0.99879546, -0.99518473, -0.98917652, -0.98078530, -0.97003127, -0.95694036, -0.94154409, -0.92387957, -0.90398933, -0.88192131, -0.85772866, -0.83146966, -0.80320759, -0.77301051, -0.74095119, -0.70710685, -0.67155902, -0.63439336, -0.59569938, -0.55557031, -0.51410283, -0.47139682, -0.42755518, -0.38268353, -0.33688995, -0.29028478, -0.24298028, -0.19509042, -0.14673058, -0.09801725, -0.04906778};typedef unsigned short u16;typedef unsigned char u8;//结构体定义typedef struct{float re[128];float im[128];} x_Str;x_Str Desc_value; //FFT倒序排列值x_Str FFT_IFFT_Odata; //FFT计算输出值//FFT/IFFT变换前倒序排列地址查询u16 dx_index(u16 i) //倒序索引{u16 n_out = 0;switch(i){case 0:{n_out= 0; break;}case 1:{n_out= 64; break;}case 2:{n_out= 32; break;}case 3:{n_out= 96; break;}case 4:{n_out= 16; break;}case 5:{n_out= 80; break;}case 6:{n_out= 48; break;}case 7:{n_out=112; break;}case 8:{n_out= 8; break;}case 9:{n_out= 72; break;}case 10:{n_out= 40; break;}case 11:{n_out=104; break;}case 12:{n_out= 24; break;}case 13:{n_out= 88; break;}case 14:{n_out= 56; break;}case 16:{n_out= 4; break;} case 17:{n_out= 68; break;} case 18:{n_out= 36; break;} case 19:{n_out=100; break;} case 20:{n_out= 20; break;} case 21:{n_out= 84; break;} case 22:{n_out= 52; break;} case 23:{n_out=116; break;} case 24:{n_out= 12; break;} case 25:{n_out= 76; break;} case 26:{n_out= 44; break;} case 27:{n_out=108; break;} case 28:{n_out= 28; break;} case 29:{n_out= 92; break;} case 30:{n_out= 60; break;} case 31:{n_out=124; break;} case 32:{n_out= 2; break;} case 33:{n_out= 66; break;} case 34:{n_out= 34; break;} case 35:{n_out= 98; break;} case 36:{n_out= 18; break;} case 37:{n_out= 82; break;} case 38:{n_out= 50; break;} case 39:{n_out=114; break;} case 40:{n_out= 10; break;} case 41:{n_out= 74; break;} case 42:{n_out= 42; break;} case 43:{n_out=106; break;} case 44:{n_out= 26; break;} case 45:{n_out= 90; break;} case 46:{n_out= 58; break;} case 47:{n_out=122; break;} case 48:{n_out= 6; break;} case 49:{n_out= 70; break;} case 50:{n_out= 38; break;} case 51:{n_out=102; break;} case 52:{n_out= 22; break;} case 53:{n_out= 86; break;} case 54:{n_out= 54; break;} case 55:{n_out=118; break;} case 56:{n_out= 14; break;} case 57:{n_out= 78; break;} case 58:{n_out= 46; break;}case 60:{n_out= 30; break;} case 61:{n_out= 94; break;} case 62:{n_out= 62; break;} case 63:{n_out=126; break;} case 64:{n_out= 1; break;} case 65:{n_out= 65; break;} case 66:{n_out= 33; break;} case 67:{n_out= 97; break;} case 68:{n_out= 17; break;} case 69:{n_out= 81; break;} case 70:{n_out= 49; break;} case 71:{n_out=113; break;} case 72:{n_out= 9; break;} case 73:{n_out= 73; break;} case 74:{n_out= 41; break;} case 75:{n_out=105; break;} case 76:{n_out= 25; break;} case 77:{n_out= 89; break;} case 78:{n_out= 57; break;} case 79:{n_out=121; break;} case 80:{n_out= 5; break;} case 81:{n_out= 69; break;} case 82:{n_out= 37; break;} case 83:{n_out=101; break;} case 84:{n_out= 21; break;} case 85:{n_out= 85; break;} case 86:{n_out= 53; break;} case 87:{n_out=117; break;} case 88:{n_out= 13; break;} case 89:{n_out= 77; break;} case 90:{n_out= 45; break;} case 91:{n_out=109; break;} case 92:{n_out= 29; break;} case 93:{n_out= 93; break;} case 94:{n_out= 61; break;} case 95:{n_out=125; break;} case 96:{n_out= 3; break;} case 97:{n_out= 67; break;} case 98:{n_out= 35; break;} case 99:{n_out= 99; break;} case 100:{n_out= 19; break;} case 101:{n_out= 83; break;} case 102:{n_out= 51; break;}case 104:{n_out= 11; break;}case 105:{n_out= 75; break;}case 106:{n_out= 43; break;}case 107:{n_out=107; break;}case 108:{n_out= 27; break;}case 109:{n_out= 91; break;}case 110:{n_out= 59; break;}case 111:{n_out=123; break;}case 112:{n_out= 7; break;}case 113:{n_out= 71; break;}case 114:{n_out= 39; break;}case 115:{n_out=103; break;}case 116:{n_out= 23; break;}case 117:{n_out= 87; break;}case 118:{n_out= 55; break;}case 119:{n_out=119; break;}case 120:{n_out= 15; break;}case 121:{n_out= 79; break;}case 122:{n_out= 47; break;}case 123:{n_out=111; break;}case 124:{n_out= 31; break;}case 125:{n_out= 95; break;}case 126:{n_out= 63; break;}case 127:{n_out=127; break;}}return n_out;}//FFT变换核心算法采用基2频法即处理数据个数为2^n//FFT_IFFT_Idata: 输入数据//N: FFT变换点数//flag: 1:正变换;0:逆变换void sp_cfftr2_dit(x_Str FFT_IFFT_Idata, u8 N, u8 flag){//内部参数定义u16 dx_cnt = 0, sx_cnt = 0; //倒序、顺序对应地址u16 Level_cnt = 0, Group_cnt = 0, A_cnt = 0; //级数、组数、个数u16 Level[7]={1,2,4,8,16,32,64};u16 L = 0;u16 wr_addr = 0; //旋转因子地址u16 up_addr = 0, dn_addr = 0; //参与蝶形运算的上、下数据地址float wcos = 0, wsin = 0; //wcos、wsin为旋转因子float cr = 0, ci = 0; //下数据与旋转因子相乘的值float Desc_re_reg = 0, Desc_im_reg = 0; //倒序排列值下数据临时寄存器//将数据进行倒序排列if(flag==1) //正变换{for(sx_cnt=0;sx_cnt<N_point;sx_cnt++){dx_cnt=dx_index(sx_cnt); //倒序排列地址查询函数Desc_value.re[dx_cnt]=FFT_IFFT_Idata.re[sx_cnt];Desc_value.im[dx_cnt]=FFT_IFFT_Idata.im[sx_cnt];}}else //逆变换{for(sx_cnt=0;sx_cnt<N_point;sx_cnt++){dx_cnt=dx_index(sx_cnt); //倒序排列地址查询函数Desc_value.re[dx_cnt]=FFT_IFFT_Idata.re[sx_cnt];Desc_value.im[dx_cnt]=-FFT_IFFT_Idata.im[sx_cnt];}}//蝶形运算程序for(Level_cnt=0;Level_cnt<N_level;Level_cnt++) //一级蝶形运算{L=Level[Level_cnt];for(Group_cnt=0;Group_cnt<N_point;) //一组蝶形运算{for(A_cnt=0;A_cnt<L;A_cnt++) //一个蝶形运算{KEY_Scan_Data_Trans(); //蝶形运算时检测按键wr_addr=(N_point*A_cnt)/(2*L); //旋转因子地址wcos=wr_re[wr_addr]; //wcos,wsin为旋转因子wsin=wr_im[wr_addr];up_addr=Group_cnt+A_cnt; //参与蝶形运算的上、下数据地址dn_addr=Group_cnt+A_cnt+L;cr=wcos*Desc_value.re[dn_addr] - wsin*Desc_value.im[dn_addr]; //下数据与旋转因子相乘的值ci=wcos*Desc_value.im[dn_addr] + wsin*Desc_value.re[dn_addr];Desc_re_reg=Desc_value.re[up_addr] - cr; //倒序排列值下数据临时寄存器Desc_im_reg=Desc_value.im[up_addr] - ci;Desc_value.re[up_addr]=Desc_value.re[up_addr] + cr; //up的值Desc_value.im[up_addr]=Desc_value.im[up_addr] + ci; //up的值Desc_value.re[dn_addr]=Desc_re_reg; //dn的值Desc_value.im[dn_addr]=Desc_im_reg; //dn的值}Group_cnt=Group_cnt+2*L;}}//对变换结果进行调整,避免数据过大if(flag==1) //正变换结果调整{for(sx_cnt=0;sx_cnt<N_point;sx_cnt++){FFT_IFFT_Odata.re[sx_cnt]=Desc_value.re[sx_cnt]/64; // 除以64FFT_IFFT_Odata.im[sx_cnt]=Desc_value.im[sx_cnt]/64; // 除以64 }}else //逆变换结果调整{for(sx_cnt=0;sx_cnt<N_point;sx_cnt++){FFT_IFFT_Odata.re[sx_cnt]= Desc_value.re[sx_cnt]*0.5; // /(N_fs*64)FFT_IFFT_Odata.im[sx_cnt]= Desc_value.im[sx_cnt]*0.5; // /(N_fs*64) }}}。

FFT算法在单片机中的使用

FFT算法在单片机中的使用
WriteCommandLCM(0x80+y_byte); WriteCommandLCM(0x80+x_Dyte+8*y_Dyte); read_data(); GDRAM_hbit=read_data(); GDRAM_lbit=read_data(); delayms(10); WriteCommandLCM(0x80+y_byte); WriteCommandLCM(0x80+x_Dyte+8*y_Dyte); delayms(10); if(x_byte;>;j)&1)*(1;=y;i--) point(x,i);
y= 63-(int)tmp; point(ii+64,y); xian(ii+64,y); } while(1); }
} //主函数 void main(void) { uchar ii,y; float tmp; //端口初始化 DDRA=0xff; PORTA=0xff; DDRB=0xff; PORTB=0xff; DDRD=0xff; PORTD=0x00; delayms(20); delayms(20); LCMInit(); //LCM 初始化 //液晶初始化 delayms(100); clear(0x00); heng(0); heng(63); su(0); 20;ii++) { x[ii].real=3; x[ii].img=0; } for (ii=20;ii<128;ii++) { x[ii].real=0; x[ii].img=0; } initw(); bitReverse(); FFT(); for(ii=64;ii<128;ii++) {

基于STM32芯片的128点FFT

基于STM32芯片的128点FFT

Main函数/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** * File Name : main.c* Author : MCD Application Team* Version : V2.0.1* Date : 06/13/2008* Description : Main program body******************************************************************************* ** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONL Y AIMS A T PROVIDING CUSTOMERS* WITH CODING INFORMA TION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SA VE TIME.* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE* CONTENT OF SUCH FIRMW ARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.******************************************************************************* //* Includes ------------------------------------------------------------------*/#include "stm32f10x_lib.h"#include "stdio.h"#include "math.h"#include "stm32_dsp.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*/#define ADC1_DR_Address ((u32)0x4001244C)#define USART1_DR_Base ((u32)0x40013804)#define LEN 128/* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/ErrorStatus HSEStartUpStatus;/* Private function prototypes -----------------------------------------------*/void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);void TIM_BaseConfiguration(void);void DMA_Configuration(void);void USART_Configuration(void);void ADC_Configuration(void);void ADC_ALL_Init(void);void FFT_Configuration(double *pr,double *pi,int n,int k,double*fr,double*fi,int l,int il);void FFT_solve(void);void Delay(u32 counter);/* Private functions ---------------------------------------------------------*/u16 data_buff[LEN];u16 px_buff[LEN];u16 pz_buff[LEN];double x[128];double pr[128];double pi[128];double fr[128];double fi[128];double mo[128];//int *px = (int*)0x1f00;//int *pz = (int*)0x1f80;int xm,zm,i,t = 0;u8 Flag = 0;/****************************************************************************** ** Function Name : main* Description : Main program* Input : None* Output : None* Return : None******************************************************************************* /int main(void){#ifdef DEBUGdebug();#endif/* System clocks configuration ---------------------------------------------*/RCC_Configuration();/* NVIC configuration ------------------------------------------------------*/NVIC_Configuration();/* GPIO configuration ------------------------------------------------------*/GPIO_Configuration();/* ADC1 configuration ------------------------------------------------------*/ADC_Configuration();/*USART Configuration--------------------------------------------------------*/USART_Configuration();ADC_ALL_Init();while (1){FFT_solve();}}/****************************************************************************** ** Function Name : RCC_Configuration* Description : Configures the different system clocks.* Input : None* Output : None* Return : None******************************************************************************* /void RCC_Configuration(void){/* RCC system reset(for debug purpose) */RCC_DeInit();/* Enable HSE */RCC_HSEConfig(RCC_HSE_ON);/* Wait till HSE is ready */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){/* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2);/* HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* PCLK1 = HCLK/2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* ADCCLK = PCLK2/4 */RCC_ADCCLKConfig(RCC_PCLK2_Div4);/* PLLCLK = 8MHz * 7 = 56 MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);/* Enable PLL */RCC_PLLCmd(ENABLE);/* Wait till PLL is ready */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}/* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* Wait till PLL is used as system clock source */while(RCC_GetSYSCLKSource() != 0x08){}}/* Enable peripheral clocks --------------------------------------------------*//* Enable DMA1 clock */RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);/* Enable USART2 clock */RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);/*Enable TIM2 clock*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);/* Enable ADC1 and GPIOC clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA, ENABLE);}/****************************************************************************** ** Function Name : GPIO_Configuration* Description : Configures the different GPIO ports.* Input : None* Output : None* Return : None******************************************************************************* /void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;/* Configure PC.04 (ADC Channel14) as analog input -------------------------*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure PA.03 (ADC Channel14) as analog input -------------------------*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);/* Configure USART1 Rx (PA.10) as input floating */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);/* Configure USART1 Tx (PA.09) as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);}/****************************************************************************** ** Function Name : NVIC_Configuration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None*******************************************************************************/void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;#ifdef VECT_TAB_RAM/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#else /* VECT_TAB_FLASH *//* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);#endif/* Enable the TIM2 gloabal Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* Enable the ADC1_EOC Interrupt */NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}/****************************************************************************** ** Function Name : TIM_BaseConfiguration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None******************************************************************************* /void TIM_BaseConfiguration(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;/* Time base configuration */TIM_TimeBaseStructure.TIM_Period = 65535;TIM_TimeBaseStructure.TIM_Prescaler = 0;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);/*Enable TIM2*/TIM_Cmd(TIM2,ENABLE);/* TIM IT enable */TIM_ITConfig(TIM2, TIM_IT_Update , ENABLE);}/****************************************************************************** ** Function Name : ADC_Configuration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None******************************************************************************* /void ADC_Configuration(void){ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; /*工作在独立模式*/ADC_InitStructure.ADC_ScanConvMode = ENABLE; /*规定了模数转换工作在扫描模式(多通道)还是单次(单通道)模式*/ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; /*规定了模数转换工作在连续还是单次模式*/ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; /*转换由软件而不是外部触发启动*/ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /*规定了ADC 数据向左边对齐还是向右边对齐*/ADC_InitStructure.ADC_NbrOfChannel = 1; /*规定了顺序进行规则转换的ADC通道的数目*/ADC_Init(ADC1, &ADC_InitStructure);}void ADC_ALL_Init(void){/* ADC1 regular channel14 configuration */ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_7Cycles5);/*设置指定ADC的规则组通道,设置它们的转化顺序和采样时间*//* Enable ADC1 EOC interrupts */ADC_ITConfig(ADC1, ADC_IT_EOC , ENABLE);/* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/* Enable ADC1 reset calibaration register */ADC_ResetCalibration(ADC1); /*重置指定的ADC的校准寄存器*//* Check the end of ADC1 reset calibration register */while(ADC_GetResetCalibrationStatus(ADC1));/*获取ADC重置校准寄存器的状态*//* Start ADC1 calibaration */ADC_StartCalibration(ADC1);/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1));/* Start ADC1 Software Conversion */ADC_SoftwareStartConvCmd(ADC1, ENABLE);/*使能指定的ADC的软件转换启动功能*/}/****************************************************************************** ** Function Name : USART_Configuration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None******************************************************************************* /void USART_Configuration(void){USART_InitTypeDef USART_InitStructure;USART_ART_BaudRate = 9600;USART_ART_WordLength = USART_WordLength_8b;USART_ART_StopBits = USART_StopBits_1;USART_ART_Parity = USART_Parity_No;USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;/* Configure USART1 */USART_Init(USART1, &USART_InitStructure);/*Enable USART1 */USART_Cmd(USART1, ENABLE);}/******************************************************************************* Function Name : FFT_Configuration* Description :* Input : None* Output : None* Return : None******************************************************************************* /void FFT_Configuration(double *pr,double *pi,int n,int k,double*fr,double*fi,int l,int il)//int n,k,l,il; double pr[],pi[],fr[],fi[];/*pr(实部),pi(虚部),n(点数),k(阶数)*/{int it,m,is,i,j,nv,l0;double p,q,s,vr,vi,poddr,poddi;/*雷德(Rader)算法,实现数据的倒位序排列-----------*/for (it=0; it<=n-1; it++){m=it;is=0;for (i=0; i<=k-1; i++){j=m/2;is=2*is+(m-2*j);m=j;}fr[it]=pr[is];fi[it]=pi[is];}pr[0]=1.0;pi[0]=0.0;p=6.283185306/(1.0*n);pr[1]=cos(p);pi[1]=-sin(p);if (l!=0)pi[1]=-pi[1];for (i=2; i<=n-1; i++){p=pr[i-1]*pr[1];q=pi[i-1]*pi[1];s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);pr[i]=p-q;pi[i]=s-p-q;}for (it=0; it<=n-2; it=it+2){vr=fr[it];vi=fi[it];fr[it]=vr+fr[it+1];fi[it]=vi+fi[it+1];fr[it+1]=vr-fr[it+1];fi[it+1]=vi-fi[it+1];}m=n/2;nv=2;for (l0=k-2; l0>=0; l0--){m=m/2;nv=2*nv;for (it=0; it<=(m-1)*nv; it=it+nv)for (j=0; j<=(nv/2)-1; j++){p=pr[m*j]*fr[it+j+nv/2];q=pi[m*j]*fi[it+j+nv/2];s=pr[m*j]+pi[m*j];s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);poddr=p-q;poddi=s-p-q;fr[it+j+nv/2]=fr[it+j]-poddr;fi[it+j+nv/2]=fi[it+j]-poddi;fr[it+j]=fr[it+j]+poddr;fi[it+j]=fi[it+j]+poddi;}}if (l!=0)for (i=0; i<=n-1; i++){ fr[i]=fr[i]/(1.0*n);fi[i]=fi[i]/(1.0*n);}if (il!=0)for (i=0; i<=n-1; i++){pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);if (fabs(fr[i])<0.000001*fabs(fi[i])){if ((fi[i]*fr[i])>0) pi[i]=90.0;elsepi[i]=-90.0;}elsepi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;}}/****************************************************************************** ** Function Name : FFT_solve* Description :* Input : None* Output : None* Return : None******************************************************************************* /void FFT_solve(void){if(Flag){/*寄存器接收满后Flag = 1,关闭ADC中断,进行FFT运算--------*/ADC_Cmd(ADC1, DISABLE);//px = (int*)0x1f00;/*转换存储位置-------------*/for(i=0;i<128;i++){//*px=data_buff[i];//px++;px_buff[i] = data_buff[i];}//px = (int*)0x1f00;/*将ADC采来的数据转换为实际的幅度值--------------*/for (i=0; i<=128; i++){//xm=*px;xm = px_buff[i];x[i]=xm/32768.0;pr[i]=x[i];/*pr数组存放函数点的实部-------------*/pi[i]=0; /*pi数组存放函数点的虚部-------------*///px++;}/*进行FFT运算----------------------*/FFT_Configuration(pr,pi,128,7,fr,fi,0,1);//pz = (int*)0x1f80;/*将最终计算出的值放入pz 中----------------------*/for (i=0;i<=128;i++){mo[i] = sqrt(fr[i]*fr[i]+fi[i]*fi[i]);zm = (int)(mo[i]*1000.0);//*pz = zm;//pz++;pz_buff[i] = zm;}}Flag = 0;}/****************************************************************************** ** Function Name : Delay* Description :* Input : None* Output : None* Return : None******************************************************************************* /void Delay(u32 counter){for(;counter > 0;counter--);}#ifdef DEBUG/****************************************************************************** ** Function Name : assert_failed* Description : Reports the name of the source file and the source line number* where the assert_param error has occurred.* Input : - file: pointer to the source file name* - line: assert_param error line source number* Output : None* Return : None******************************************************************************* /void assert_failed(u8* file, u32 line){/* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* Infinite loop */while (1){}}#endif/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/stm32f10x_it.c/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** * File Name : stm32f10x_it.c* Author : MCD Application Team* Version : V2.0.1* Date : 06/13/2008* Description : Main Interrupt Service Routines.* This file provides template for all exceptions handler* and peripherals interrupt service routine.******************************************************************************* ** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONL Y AIMS A T PROVIDING CUSTOMERS* WITH CODING INFORMA TION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SA VE TIME.* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE* CONTENT OF SUCH FIRMW ARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.******************************************************************************* //* Includes ------------------------------------------------------------------*/#include "stm32f10x_it.h"#include "stdio.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*/#define ADC1_DR_Address ((u32)0x4001244C)#define LEN 128/* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*/extern u16 data_buff[LEN];extern int t ;extern u8 Flag;u32 *P = (u32*)0x4001244C;/****************************************************************************** ** Function Name : NMIException* Description : This function handles NMI exception.* Input : None* Output : None* Return : None******************************************************************************* /void NMIException(void){}/****************************************************************************** ** Function Name : HardFaultException* Description : This function handles Hard Fault exception.* Input : None* Output : None* Return : None******************************************************************************* /void HardFaultException(void){/* Go to infinite loop when Hard Fault exception occurs */while (1){}}/****************************************************************************** ** Function Name : MemManageException* Description : This function handles Memory Manage exception.* Input : None* Output : None* Return : None******************************************************************************* /void MemManageException(void){/* Go to infinite loop when Memory Manage exception occurs */while (1){}}/****************************************************************************** ** Function Name : BusFaultException* Description : This function handles Bus Fault exception.* Input : None* Output : None* Return : None******************************************************************************* /void BusFaultException(void){/* Go to infinite loop when Bus Fault exception occurs */while (1){}}/****************************************************************************** ** Function Name : UsageFaultException* Description : This function handles Usage Fault exception.* Input : None* Output : None* Return : None******************************************************************************* /void UsageFaultException(void){/* Go to infinite loop when Usage Fault exception occurs */while (1){}}/****************************************************************************** ** Function Name : DebugMonitor* Description : This function handles Debug Monitor exception.* Input : None* Output : None* Return : None******************************************************************************* /void DebugMonitor(void){}/****************************************************************************** ** Function Name : SVCHandler* Description : This function handles SVCall exception.* Input : None* Output : None* Return : None******************************************************************************* /void SVCHandler(void){}/****************************************************************************** ** Function Name : PendSVC* Description : This function handles PendSVC exception.* Input : None* Output : None* Return : None******************************************************************************* /void PendSVC(void){}/****************************************************************************** ** Function Name : SysTickHandler* Description : This function handles SysTick Handler.* Input : None* Output : None* Return : None******************************************************************************* /void SysTickHandler(void){}/****************************************************************************** ** Function Name : WWDG_IRQHandler* Description : This function handles WWDG interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void WWDG_IRQHandler(void){}/****************************************************************************** ** Function Name : PVD_IRQHandler* Description : This function handles PVD interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void PVD_IRQHandler(void){}/****************************************************************************** ** Function Name : TAMPER_IRQHandler* Description : This function handles Tamper interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void TAMPER_IRQHandler(void){}/****************************************************************************** ** Function Name : RTC_IRQHandler* Description : This function handles RTC global interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void RTC_IRQHandler(void){}/****************************************************************************** ** Function Name : FLASH_IRQHandler* Description : This function handles Flash interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void FLASH_IRQHandler(void){}/****************************************************************************** ** Function Name : RCC_IRQHandler* Description : This function handles RCC interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void RCC_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI0_IRQHandler* Description : This function handles External interrupt Line 0 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI0_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI1_IRQHandler* Description : This function handles External interrupt Line 1 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI1_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI2_IRQHandler* Description : This function handles External interrupt Line 2 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI2_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI3_IRQHandler* Description : This function handles External interrupt Line 3 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI3_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI4_IRQHandler* Description : This function handles External interrupt Line 4 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI4_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel1_IRQHandler* Description : This function handles DMA1 Channel 1 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel1_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel2_IRQHandler* Description : This function handles DMA1 Channel 2 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel2_IRQHandler(void){}/******************************************************************************** Function Name : DMA1_Channel3_IRQHandler* Description : This function handles DMA1 Channel 3 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel3_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel4_IRQHandler* Description : This function handles DMA1 Channel 4 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel4_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel5_IRQHandler* Description : This function handles DMA1 Channel 5 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel5_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel6_IRQHandler* Description : This function handles DMA1 Channel 6 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel6_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel7_IRQHandler* Description : This function handles DMA1 Channel 7 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel7_IRQHandler(void){}/****************************************************************************** ** Function Name : ADC1_2_IRQHandler* Description : This function handles ADC1 and ADC2 global interrupts requests.* Input : None* Output : None* Return : None******************************************************************************* /void ADC1_2_IRQHandler(void){if(ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET){ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);//*P = ADC1_DR_Address;data_buff[t] = *P;t++;while(t == 128){Flag = 1;t = 0;}}}。

嵌入式系统中FFT算法研究 (128点参考)

嵌入式系统中FFT算法研究  (128点参考)

摘要:首先分析实数FFT算法的推导过程,然后给出一种具体实现FFT算法的C语言程序,可以直接应用于需要FFT运算的单片机或DSP等嵌入式系统中。

关键词:嵌入式系统FFT算法单片机DSP目前国内有关数字信号处理的教材在讲解快速傅里叶变换(FFT)时,都是以复数FFT为重点,实数FFT算法都是一笔带过,书中给出的具体实现程序多为BASIC或FORTRAN程序并且多数不能真正运行。

鉴于目前在许多嵌入式系统中要用到FFT运算,如以DSP为核心的交流采样系统、频谱分析、相关分析等。

本人结合自己的实际开发经验,研究了实数的FFT算法并给出具体的C语言函数,读者可以直接应用于自己的系统中。

1 倒位序算法分析按时间抽取(DIT)的FFT算法通常将原始数据倒位序存储,最后按正常顺序输出结果X(0),X(1),...,X(k),...。

假设一开始,数据在数组float dataR[128]中,我们将下标i表示为(b6b5b4b3b2b1b0)b,倒位序存放就是将原来第i个位置的元素存放到第(b0b1b2b3b4b5b6)b的位置上去.由于C语言的位操作能力很强,可以分别提取出b6、b5、b4、b3、b2、b1、b0,再重新组合成b0、b1、b2、b3、b4、b5、b6,即是倒位序的位置。

程序段如下(假设128点FFT):/* i 为原始存放位置,最后得invert_pos 为倒位序存放位置 */ int b0=b1=b2=b3=b4=b5=6=0; b0=i&0x01; b1=(i/2)&0x01; b2=(i/4)&0x01; b3=(i/8)&0x01; b4=(i/16)&0x01; b5=(i/32)&0x01; b6=(i/64)&0x01;/*以上语句提取各比特的0、1值*/invert_pos=b0*64+b1*32+b2*16+b3*8+b4*4+b5*2+b6; 大家可以对比教科书上的倒位序程序,会发现这种算法充分利用了C 语言的位操作能力,非常容易理解而且位操作的速度很快。

FPGA课程设计128点FFT变换的FPGA实现

FPGA课程设计128点FFT变换的FPGA实现
In_re[15..0]:复数的实部,位宽16位,但有效位不得超过14位。Start拉高的同时,必须出现第一个有效的实部数据。
Busy: 在Start生效之后,FFT运算器将其拉高。表明开始一帧数据的输入,运算与输出。此时不能将Start再次拉高,只有Busy恢复低电平时,才能将Start拉高进行下一帧。
2
2.1 OFDM 的基本原理
正交频分复用(OFDM)技术与已经普遍应用的频分复用技术十分相似。与普通的频分复用基本原理相同,OFDM 把高速的数据流通过串并变换分配到速率相对较低的若干个频率子信道中进行传输,不同的是,OFDM 技术更好地利用了控制方法,使频谱利用率有所提高。
2.1.1 OFDM 的产生和发展
1.1.1 无线通信的发展和现状
现代无线通信技术的发展始于本世纪 20 年代,经历了早期专用移动通信系统的发展,公用移动通信业务的发展,到 1978 年底,美国贝尔试验室研制成功先进移动电话系统(AMPS),建成了蜂窝状移动通信网,大大提高了系统容量。随后投入商用,服务区域在美国逐渐扩大。其它工业化国家也相继开发出蜂窝式公用移动通信网,这种模拟通信系统被称为第一代移动通信系统。
(3-13)
(3-14)
这样一个N点的DFT就被拆分成为了两个N/2点的DFT。式(3-7)和式(3-8)说明了原N点的DFT和这两个N/2点的DFT之间的关系。
采用蝶形运算符号的这种图示方法,可以用图3-1来表示前面所讲到的运算。在图3.2中,N= =8,式(3-13)给出了X(0)~X(3)的计算方法,而式(2-14)给出了X(4)~X(7)的计算方法。
, (3-5)
, (3-6)
那么x(n)的DFT为
(3-7)
由于
(3-8)

TI库实现2048点或更大点数FFT

TI库实现2048点或更大点数FFT

在DSP运算中,经常需要把输入时域信号在频域进行处理之后,再还原为时域信号,这样就需要进行FFT 和IFFT运算:x(n) -> FFT -> X(f) -> 频域处理-> Y(f) -> IFFT -> y(n)而一般的DSP芯片只支持整数运算,也就是说只能进行定点小数计算。

N点FFT计算出0… N-1,N个复数:0,A,N/2,A*,A为(N/2-1)个复数,A*为A的共轭复数。

FFT的公式为:NX(k) = sum x(n)*exp(-j*2*pi*(k-1)*(n-1)/N)、1 < = k < = N.n = 1IFFT的公式为:Nx(n) = (1/N) sum X(k)*exp( j*2*pi*(k-1)*(n-1)/N)、1 < = n < = N.k = 1假设我们对ADC转换器转换的数字信号进行FFT运算,若输入数据为16bit的短整型数,我们可以把它看作Q15的从-1到1之间的小数。

根据FFT的公式我们可以知道,FFT变换之后的结果将超出这个范围。

例如在matlab中输入fft(sin([1:8]*0.5)),可以看到结果:2.8597,-0.8019 -3.0216i,0.4312 - 0.8301i,0.5638 - 0.3251i,0.5895,0.5638 + 0.3251i,0.4312 + 0.8301i,-0.8019 + 3.0216i实际上,FFT变换之后的数据的范围在-N到N之间,N为FFT的点数。

为了正确地表达-N到N之间的数值,输出数据的Q值将变小,例如若N=1024,输入数据为Q15的话,那么输出数据则必须为Q5才能够确保结果不会溢出。

这样的结果将丢失很多信息,以至于IFFT无法还原为原来的数据。

如下图所示:Q15 -> 1024FFT -> Q5 -> 1024IFFT -> Q5这样,经过FFT和IFFT变换之后,数据从Q15变成了Q5,丢失了10bit的信息。

matlab的fft用法

matlab的fft用法

matlab的fft用法FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域。

有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。

这就是很多信号分析采用FFT变换的原因。

另外,FFT可以将一个信号的频谱提取出来,这在频谱分析方面也是经常用的。

虽然很多人都知道FFT是什么,可以用来做什么,怎么去做,但是却不知道FFT 之后的结果是什意思、如何决定要使用多少点来做FFT。

一个模拟信号,经过ADC采样之后,就变成了数字信号。

采样定理告诉我们,采样频率要大于信号频率的两倍,这些我就不在此罗嗦了。

采样得到的数字信号,就可以做FFT变换了。

N 个采样点,经过FFT之后,就可以得到N个点的FFT结果。

为了方便进行FFT运算,通常N取2的整数次方。

二、计算序列的FFT变换求序列{2,3,3,2}的DFT变换。

>> N=4;>> n=0:N-1;>> xn=[2 3 3 2];>> xk=fft(xn)运算结果如下:xk =10.0000 + 0.0000i -1.0000 - 1.0000i 0.0000 + 0.0000i -1.0000 + 1.0000i带入公式检验:X [ k ] = ∑ n = 0 N − 1 X [ n ] W N n k X[k]=\sum_{n=0}^{N-1}X[n]W_N^{nk} X[k]=n=0∑N−1X[n]WNnkX [ 0 ] = 2 W 4 0 + 3 W 4 0 + 3 W 4 0 + 2 W 4 0 = 10X[0]=2W_4^{0}+3W_4^{0}+3W_4^{0}+2W_4^{0}=10 X[0]=2W40 +3W40+3W40+2W40=10X [ 1 ] = 2 W 4 0 + 3 W 4 1 + 3 W 4 2 + 2 W 4 3 = − 1 − i X[1]=2W_4^{0}+3W_4^{1}+3W_4^{2}+2W_4^{3}=-1-iX[1]=2W40+3W41+3W42+2W43=−1−iX [ 2 ] = 2 W 4 0 + 3 W 4 2 + 3 W 4 4 + 2 W 4 6 = 0X[2]=2W_4^{0}+3W_4^{2}+3W_4^{4}+2W_4^{6}=0 X[2]=2W40+3W42+3W44+2W46=0X [ 3 ] = 2 W 4 0 + 3 W 4 3 + 3 W 4 6 + 2 W 4 9 = − 1 + i X[3]=2W_4^{0}+3W_4^{3}+3W_4^{6}+2W_4^{9}=-1+iX[3]=2W40+3W43+3W46+2W49=−1+i公式运算结果与matlab仿真结果一致。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档