2015-08-29 10:08 AM
Hi. I am facing strange problem implementing FFT on stm32f4 kit. i am using Virtual Com Port to transmit serial data which is plotted on QT (C++) platform.
The problem i am facing is that some time output is correct but most of the times wrong data is being plotted. Even when correct data is plotted still some wrong samples arethere to ruin theplot. Here is my code. Any help would be appreciated. Thanks in advance.===== CODE =====&sharpdefine FFT_SAMPLES 2048&sharpdefine FFT_SIZE FFT_SAMPLES/2&sharpdefine FFT_TIM_PRESCALE 420-1// 100 KH-z Clock&sharpdefine FFT_TIM_PERIOD 10-1//100 KHz down to 10 Khz&sharpdefine FFT_SAMPLE_FRQ ADC_SampleTime_15Cycles &sharpdefine FFT_SAMPLE_DELAY ADC_TwoSamplingDelay_5Cyclesuint16_t fftAdc[FFT_SAMPLES/2];float32_t fftInput[FFT_SAMPLES];float32_t fftOutput[FFT_SIZE];uint16_t fftInc=0;uint16_t fftI=0;double fftAdcValue;//after conversion -1 to +1uint32_t fftMaxIndex;float32_t fftMaxValue;uint8_t fftFlag=0;int main(void){ arm_cfft_radix4_instance_f32 FFT_InitStruc; FFT_NVIC_ADC(); FFT_GPIO(); FFT_TIM2(); FFT_ADC(); status = arm_cfft_radix4_init_f32(&FFT_InitStruc,FFT_SIZE,0,1); while(1){ if(fftFlag == 1){ fftFlag = 0; arm_cfft_radix4_f32(&FFT_InitStruc,fftInput); arm_cmplx_mag_f32(fftInput,fftOutput,FFT_SIZE); arm_max_f32(fftOutput,FFT_SIZE,&fftMaxValue,&fftMaxIndex); if(fftMaxIndex >= FFT_SIZE/2){ fftMaxIndex = FFT_SIZE - fftMaxIndex; } for(frInc=0;frInc<FFT_SIZE/2;frInc+=16){ sprintf(strPut,''♯%d+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%.0f+%d+%.0f+~'',frInc,fftOutput[frInc],fftOutput[frInc+1], fftOutput[frInc+2],fftOutput[frInc+3],fftOutput[frInc+4],fftOutput[frInc+5],fftOutput[frInc+6],fftOutput[frInc+7],fftOutput[frInc+8],fftOutput[frInc+9],fftOutput[frInc+10],fftOutput[frInc+11], fftOutput[frInc+12],fftOutput[frInc+13],fftOutput[frInc+14],fftOutput[frInc+15],fftMaxIndex,fftMaxValue); TM_USB_VCP_Puts(strPut); Delay(7000); } } } }void FFT_GPIO(void){ GPIO_InitStruc.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruc.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStruc.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStruc.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA,&GPIO_InitStruc); }void FFT_NVIC_ADC(void){ NVIC_InitStruc.NVIC_IRQChannel = ADC_IRQn; NVIC_InitStruc.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruc.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruc.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStruc); }void FFT_TIM2(void){ TIM_DeInit(TIM2); TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruc); TIM_TimeBaseInitStruc.TIM_Period = FFT_TIM_PERIOD; TIM_TimeBaseInitStruc.TIM_Prescaler = FFT_TIM_PRESCALE; TIM_TimeBaseInitStruc.TIM_ClockDivision = 0; TIM_TimeBaseInitStruc.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruc.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruc); TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update); TIM_Cmd(TIM2,ENABLE); }void FFT_ADC(void){ DMA_DeInit(DMA2_Stream0); DMA_InitStruc.DMA_Channel = DMA_Channel_0; DMA_InitStruc.DMA_PeripheralBaseAddr = (uint32_t) &ADC1->DR; DMA_InitStruc.DMA_Memory0BaseAddr = (uint32_t) &fftAdc[0]; DMA_InitStruc.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStruc.DMA_BufferSize = FFT_SIZE; DMA_InitStruc.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruc.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruc.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStruc.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruc.DMA_Mode = DMA_Mode_Circular; DMA_InitStruc.DMA_Priority = DMA_Priority_High; DMA_InitStruc.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStruc.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStruc.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStruc.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0,&DMA_InitStruc); DMA_Cmd(DMA2_Stream0,ENABLE); ADC_DeInit(); ADC_CommonInitStruc.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStruc.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStruc.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStruc.ADC_TwoSamplingDelay = FFT_SAMPLE_DELAY; ADC_CommonInit(&ADC_CommonInitStruc); ADC_InitStruc.ADC_Resolution = ADC_Resolution_12b; ADC_InitStruc.ADC_ScanConvMode = DISABLE; ADC_InitStruc.ADC_ContinuousConvMode = DISABLE; ADC_InitStruc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; ADC_InitStruc.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; ADC_InitStruc.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStruc.ADC_NbrOfConversion = 1; ADC_Init(ADC1,&ADC_InitStruc); ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,FFT_SAMPLE_FRQ); ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE); ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE); ADC_DMACmd(ADC1,ENABLE); ADC_Cmd(ADC1,ENABLE); ADC_SoftwareStartConv(ADC1); }void ADC_IRQHandler(void){ float32_t *pData; uint16_t *pConvertedValues; ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);{ if(fftFlag ==0){ fftFlag = 1; pData = &(fftInput[0]); pConvertedValues = & (fftAdc[0]); for(fftI =0;fftI<FFT_SIZE;fftI++){ *pData = (float32_t) ((float32_t)*pConvertedValues - (float32_t) 2048) / (float32_t) 2048; pData ++; *pData = 0; pData ++; pConvertedValues ++; } } }} #discovery #fft #stm32f42015-08-29 12:30 PM
Not sure the EOC method is going to work, are you trying to do an FFT at each sample?
Realistically if you're going to use DMA, and perform an FFT on the buffer you are going to need to double the buffer size, and interrupt on the HT (Half Transfer) and TC (Transfer Complete) and process the half of the buffer that's NOT be actively loaded behind the scenes. The FFT portion you might want to test by providing known data sets and confirming all is well there.2015-08-29 09:45 PM
As u said, I performed the fft on test array (which was working on Matlab) but
the output bins are keep increasing. Could u plz point out mistake in my code.From: clive1Posted: Saturday, August 29, 2015 9:30 PMSubject: FFT problem on stm32f4 discovery.Not sure the EOC method is going to work, are you trying to do an FFT at each sample?
Realistically if you're going to use DMA, and perform an FFT on the buffer you are going to need to double the buffer size, and interrupt on the HT (Half Transfer) and TC (Transfer Complete) and process the half of the buffer that's NOT be actively loaded behind the scenes. The FFT portion you might want to test by providing known data sets and confirming all is well there.2015-08-29 09:45 PM
As u said, I performed the fft on test array (which was working on Matlab) but
the output bins are keep increasing. Could u plz point out mistake in my code.From: clive1Posted: Saturday, August 29, 2015 9:30 PMSubject: FFT problem on stm32f4 discovery.Not sure the EOC method is going to work, are you trying to do an FFT at each sample?
Realistically if you're going to use DMA, and perform an FFT on the buffer you are going to need to double the buffer size, and interrupt on the HT (Half Transfer) and TC (Transfer Complete) and process the half of the buffer that's NOT be actively loaded behind the scenes. The FFT portion you might want to test by providing known data sets and confirming all is well there.2015-08-29 09:45 PM
As u said, I performed the fft on test array (which was working on Matlab) but
the output bins are keep increasing. Could u plz point out mistake in my code.From: clive1Posted: Saturday, August 29, 2015 9:30 PMSubject: FFT problem on stm32f4 discovery.Not sure the EOC method is going to work, are you trying to do an FFT at each sample?
Realistically if you're going to use DMA, and perform an FFT on the buffer you are going to need to double the buffer size, and interrupt on the HT (Half Transfer) and TC (Transfer Complete) and process the half of the buffer that's NOT be actively loaded behind the scenes. The FFT portion you might want to test by providing known data sets and confirming all is well there.2015-08-29 09:49 PM
I have checked adc function separately its giving me the right conversions. But when i
performed fft on test array(tested on matlab) the output bins are keep increasing. Could u plz point out mistake in my code. Tanks2016-02-09 07:33 AM
Hi,
I am trying to Implement real time FFT Using STM32F4. Regarding to DSP libraries I am facing some Problems. If you Solved your Issue; Can you help me in that.