基于LPC55S69双核ARM-M33的FFT傅利叶频谱仪
一、项目名称
基于LPC55S69双核ARM-M33的FFT傅利叶频谱仪
二、项目概述
傅利叶运算FFT很适用于频谱的分析。基于LPC55S69双核ARM-M33的FFT傅利叶频谱仪,利用M33双核ARM主核浮点运算的特点,Core0进行ADC采样和FFT运算。Core1驱动OLED将运算结果以图形方式显示频谱。
三、项目的实施
双核任务的规划:
项目主要功能为每秒512点的FFT运算,其中主要分为0#模块(ADC采样、FFT浮点小数运算)和1#模块(OLED图形显示)。0#模块分配给Core0,1#模块分配给Core1。申请了一个内存共享区,Core0将512个点FFT运算结果存放在该区,Core1读取该共享数据在OLED上显示。
本项目使用了IAR自带的DSP库和LPC的PowerQuad两种DSP进行测试。
硬件资源:
实现项目的功能利用《基于LPC55S69双核三相真有效值交流电压表》的硬件资源。Core0的资源需要ADC0通道的采样转换。Core1驱动OLED的5条GPIO口线硬件资源不变直接利用。这些都从板子上的ARDUINO插座上引出。
外扩资源:
需要外扩ADC外部输入电路ADC0输入利用原《真有效值交流电压表》的硬件ADC0,见图1。
图1
DEMO板的三相交流电模拟信号发生器,输出的正弦波信号,连接到LPC55S69的ADC0输入端,在P3端接上9V层叠电池就能进行50HZ正弦波频谱的显示。由于这片OLED水平方向只有128DPI,扣除512点FFT的镜像部分256点,将前256点压缩每2点抽取1点共128点供水平显示。如果断开用50HZ发生器的9V供电,用户也可以将MP3信号从S1(GND)和S2(信号)接入来测试(见图2)。注意信号电平勿超过3.3V供电电压。
开发环境:
IAR8.32.1。工程模块使用双核Hello_world修改而成。
为了对比使用IAR自带DSP函数库与LPC5500独特的PowerQuad处理浮点运算的能力,代码使用了方案A(IAR DSP)和方案B(LPC PowerQuad):
方案A;使用IAR自带DSP库,需要调用IAR的DSP库,见图2.
图2
FPU要使能(图3)
图3
FFT 运算直接调用IAR的DSP库,代码不复杂:
Void LPC_FFT(void)
{
arm_cfft_radix2_instance_f32 scfft;
uint16_t i;
arm_cfft_radix2_init_f32(&scfft,FFT_LENGTH,0,1);
for(i=0;i<FFT_LENGTH;i++)
{ fft_inputbuf[2*i]=(uint16_t)Adc_Value[i];
fft_inputbuf[2*i+1]=0;
}
arm_cfft_radix2_f32(&scfft,fft_inputbuf);
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH);
}
双核调试:
调试过程与真有效交流电压表基本相同,不再重复。
演示代码测试了LPC55s69主核处理浮点运算处理512个点FFT的浮点运算速度,,测试结果大约耗时1156uS(图4)。
图4
方案B:使用LPC的POWERQUAD
该测试使用Core0单核工程添加fsl_powerquad.c、fsl_widdlefactor.c和DSP原代码(图5)。
图5
使能FPU(图6)。
图6
void task_pq_fft_512(void)
{
arm_cfft_instance_q31 instance;
uint32_t i;
for (i = 0; i < APP_PQ_FFT_SAMPLE_COUNT_512; i++)
{ gPQFftF32In[i*2] = (float32_t)(Adc_Value[i]-2047.99);
gPQFftF32In[i*2] /= 3.0f;
gPQFftF32In[i*2+1] = 0.0f;
}//导入ADC数据
arm_float_to_q31(gPQFftF32In,gPQFftQ31In, APP_PQ_FFT_SAMPLE_COUNT_512*2u);
for (i = 0u; i < APP_PQ_FFT_SAMPLE_COUNT_512 * 2u; i++)
{ gPQFftQ31InOut[i] = gPQFftQ31In[i] >> 5u; }
TimerCount_Start();
instance.fftLen = APP_PQ_FFT_SAMPLE_COUNT_512;
arm_cfft_q31(&instance, gPQFftQ31InOut, 0, 1);
TimerCount_Stop(calcTime);
for (i = 0u; i < APP_PQ_FFT_SAMPLE_COUNT_512 * 2u; i++)
{ gPQFftQ31Out[i] = gPQFftQ31InOut[i] << 5u;
}
arm_q31_to_float(gPQFftQ31Out,gPQFftF32Out, APP_PQ_FFT_SAMPLE_COUNT_512*2u);
arm_cmplx_mag_f32( gPQFftF32Out, gPQFftF32In, APP_PQ_FFT_SAMPLE_COUNT_512);
memset(gLcdFreqSpecDispBuf,0u, sizeof(gLcdFreqSpecDispBuf));
for (i = 0u; i < APP_PQ_FFT_SAMPLE_COUNT_512; i++)
{ gLcdFreqSpecDispBuf[i] = (int)(gPQFftF32In[i] * 128.0); }
gPQProcCycles[APP_USER_TASK_FFT_512_IDX] = calcTime;
}
使用POWERQUAD使得FFT浮点运算速度大大提高,处理512点FFT浮点运算耗时36uS(图7)。
图7
通过方案A(图4)与方案B(图7)运行结果对比可知,LPC5500特有的PowerQuad处理浮点运算的速度比IAR自带的DSP处理速度大大提高。