STM32f429使用DSP库相应函数进行FFT、IFFT、复数共轭、相乘等 *** 作

STM32f429使用DSP库相应函数进行FFT、IFFT、复数共轭、相乘等 *** 作,第1张

STM32F4中进行FFT等复数运算相应函数使用方法,使用友善串口助手查看函数运行结果
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "math.h"
#include "arm_math.h"
#include "arm_const_structs.h"
/************************************************
 ALIENTEK 阿波罗STM32F429开发板实验3
 串口实验-HAL库函数版
 技术支持:www.openedv.com
 淘宝店铺:http://eboard.taobao.com 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/
#define F 10  //
#define PI2 6.28318530717959

__IO uint16_t  ADC1ConvertedValue[4096];

float rfft_inputbuf[F];
float rfft_outputbuf[F*2];
float routputbuf[F];//幅度输出数组

float cfft_inputbuf[F*2];
//float cfft_outputbuf[4096*2];
float coutputbuf[F];//幅度输出数组

float conj_rfft_outputbuf[F*2];
	float squared_rfft_outputbuf[F];

	float mult_fft_outputbuf[F*2];
	float mult_real_fft_outputbuf[F*2];
	float sub_fft_outputbuf[F*2];
	float scale_fft_outputbuf[F*2];


int main(void)
{
    
	
//    u8 len;	
//	u16 times=0; 
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    uart_init(115200);              //初始化USART
    LED_Init();                     //初始化LED 
    KEY_Init();                     //初始化按键

	for(int j =0; j<F; j++)
	{
		rfft_inputbuf[j]=0.0f;
		routputbuf[j]=0.0f;
				squared_rfft_outputbuf[j]=0.0f;
		coutputbuf[j]=0.0f;
	}
	for(int j =0; j<F*2; j++)
	{
		rfft_outputbuf[j]=0.0f;
		cfft_inputbuf[j]=0.0f;
				conj_rfft_outputbuf[j]=0.0f;
				mult_fft_outputbuf[j]=0.0f;
				mult_real_fft_outputbuf[j]=0.0f;
				sub_fft_outputbuf[j]=0.0f;
				scale_fft_outputbuf[j]=0.0f;
//		cifft_inputbuf[j]=0.0f;
	}	
	
	uint16_t i; 
	arm_rfft_fast_instance_f32 S; 

	 /* 实数序列FFT长度 */ 
	uint16_t fftSize = F;  
	 /* 正变换 */ 
    uint8_t ifftFlag = 0;  

	/* 初始化结构体S中的参数 */ 
	arm_rfft_fast_init_f32(&S, fftSize); 

     
	for(i=0; i<F; i++) 
	{ 
    /*  */ 
    rfft_inputbuf[i] = 2*arm_sin_f32(PI2*i*38.0/F) + 
               3*arm_sin_f32(PI2*i*47.0/F)  + 
               4*arm_sin_f32(PI2*i*23.0/F); 
	} 
	
	printf("rfft_inputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_inputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
  /* fftSize点实序列快速FFT  ,无法使用此函数进行傅里叶逆变换*/  
  arm_rfft_fast_f32(&S, rfft_inputbuf, rfft_outputbuf, ifftFlag); 

	printf("2-rfft_inputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_inputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	printf("rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	/* 实序列快速iFFT ,  无法使用此函数进行傅里叶逆变换*/ 	
//	arm_rfft_fast_f32(&S, rifft_inputbuf, rifft_outputbuf, 1);
//	
//  /*    
//  */  
	
	
   arm_cmplx_mag_f32(rfft_outputbuf, routputbuf, fftSize); 
	
	printf("2—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	printf("绝对值\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", routputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	//复数共轭  每个数组都有2*fftSize个值
	arm_cmplx_conj_f32(rfft_outputbuf,conj_rfft_outputbuf,fftSize);
	
	printf("3—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	printf("共轭3—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", conj_rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	//
	/*复数能量  计算复数数据向量元素的幅度平方,数据以交错方式存储(real, imag, real, imag, ...)。
	   输入数组有2*fftSize个值,输出数组共有fftSize个值*/
	arm_cmplx_mag_squared_f32(rfft_outputbuf,squared_rfft_outputbuf,fftSize);
	
	printf("4—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	printf("复数能量4—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", squared_rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	//
	for(i=0; i<fftSize; i++) 
    { 
		squared_rfft_outputbuf[i]=i;
    }
	/*复数乘法  将一个复数向量乘以另一个复数向量并生成一个复数结果。复数数组中的数据以交错方式存储(real, imag, real, imag, ...)。
	  该参数numSamples表示处理的复杂样本的数量。
	  复数数组总共有2*fftSize实数值。每个数组都有2*fftSize个值*/
	arm_cmplx_mult_cmplx_f32 (rfft_outputbuf,squared_rfft_outputbuf,mult_fft_outputbuf,fftSize);
	
	printf("5—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	printf("复数乘法5—rfft_outputbuf*fft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", mult_fft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	//
	
	/*复数与实数相乘  将复数向量乘以实数向量并生成复数结果(实部与虚部乘以对应的相同的一个实数)。
	  复数数组中的数据以交错方式存储(real, imag, real, imag, ...)。
	   该参数numSamples表示处理的复杂样本的数量。
	   复数数组有一个2*fftSize实数值,而实数数组有一个fftSize实数值,输出数组有一个2*fftSize实数值。*/
	arm_cmplx_mult_real_f32(rfft_outputbuf,squared_rfft_outputbuf,mult_real_fft_outputbuf,fftSize);
	
	printf("6—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	
	
	printf("复数与实数相乘6—rfft_outputbuf*squared_rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", mult_real_fft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	//
	/*向量减法   两个向量的逐元素减法*/
	arm_sub_f32(rfft_outputbuf,mult_real_fft_outputbuf,sub_fft_outputbuf,2*fftSize);
	
	printf("7—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	printf("向量减法7—rfft_outputbuf-mult_real_fft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", sub_fft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	//
	/*向量乘法   将向量乘以标量值*/
	arm_scale_f32(rfft_outputbuf,3.3,scale_fft_outputbuf,2*fftSize);
	
	printf("8—rfft_outputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	printf("向量乘以标量值8—rfft_outputbuf*3.3\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", scale_fft_outputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	
	float max;
	uint32_t num;
	for(i=0; i<fftSize; i++) 
    { 
		rfft_inputbuf[i]=9; 
		
    }
	/*计算数据数组的最大值。该函数返回最大值及其在数组中的位置,数字下表从0开始,若有多个值则返回第一个下标*/
	arm_max_f32(rfft_inputbuf,fftSize,&max,&num);
	
	printf("rfft_inputbuf\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_inputbuf[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	printf("最大值\n"); 
	
		printf("%f\r\n", max); 
	printf("在数组中的位置\n");
		printf("%d\r\n", num); 
		LED0=!LED0;
		delay_ms(40);
    
	float rfft_inputbuf22[F];
	/*样本复制  将样本从源向量复制到目标向量*/
	arm_copy_f32(rfft_inputbuf,rfft_inputbuf22,fftSize);// ( float32_t *pSrc, float32_t *pDst, uint32_t blockSize )
	
	printf("rfft_inputbuf22\n"); 
	for(i=0; i<fftSize; i++) 
    { 
		printf("%f\r\n", rfft_inputbuf22[i]); 
		LED0=!LED0;
		delay_ms(40);
    }
	
	
	
	
	
	
	
	for (int i = 0; i < F*2; i++)
	{
		//cfft_inputbuf[i * 2] = ADC1ConvertedValue[i] * 3.3 / 4096;//实部赋值,* 3.3 / 4096是为了将ADC采集到的值转换成实际电压
		cfft_inputbuf[i * 2] = 500+1000*arm_sin_f32(PI2*i*50.0/F) + 
               2000*arm_sin_f32(PI2*i*1500.0/F)  + 
               3000*arm_sin_f32(PI2*i*1550.0/F);
		cfft_inputbuf[i * 2 + 1] = 0;//虚部赋值,固定为0.
	}
	
	 
	
	uint32_t doBitReverse = 1;
 	/* Process the data through the CFFT/CIFFT module */
	arm_cfft_f32(&arm_cfft_sR_f32_len4096, cfft_inputbuf, ifftFlag, doBitReverse);

	arm_cfft_f32(&arm_cfft_sR_f32_len4096, cfft_inputbuf, 1, doBitReverse);
	
  /* Process the data through the Complex Magnitude Module for
  calculating the magnitude at each bin */
	arm_cmplx_mag_f32(cfft_inputbuf, coutputbuf, fftSize);
	
//	for(i=0; i
//    { 
//		printf("%f\r\n", cfft_inputbuf[i]); 
//		LED0=!LED0;
//		delay_ms(40);
//    } 
	
//	
//	for(i=0; i
//    { 
//		printf("%f\r\n", routputbuf[i]); 
//		LED0=!LED0;
//		delay_ms(20);
//    } 
//	

	
	
/*串口将32位浮点类型数据分成4次发送,每次传输一个字节	
	float  var_f = 2, my_float;
	u16  j, num;
	char *char_ptr;
	float *buff;
	char pc_rx_buf[4];
	num = sizeof(float);
	printf("float存储大小:%d \n", num);
	char_ptr = (char*)(&var_f);
	

	for (j = 0; j < num; j++)
	{
		printf("第%d位的地址:%p\n", j + 1, char_ptr + j);
		printf("第%d位的数据:%x\n", j + 1, *(char_ptr + j));
		pc_rx_buf[j] = *(char_ptr + j);
	}
	buff = (float*)(pc_rx_buf);
	printf("pc_rx_buf的地址:%p\n", &pc_rx_buf);
	my_float = *buff;

	printf("接收的数值为:%f\n", my_float);
*/	

	//HAL_UART_Transmit(&UART1_Handler,(uint8_t*)pc_rx_buf,4,1000);	//发送接收到的数据
	//while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);		//等待发送结束
	printf("\r\n\r\n");//插入换行
	
    while(1)
	{
		LED0=!LED0;
		delay_ms(1000);
	};
    
		
}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1354263.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-14
下一篇2022-06-14

发表评论

登录后才能评论

评论列表(0条)

    保存