赞
踩
ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING
第一个宏:
M3:ARM_MATH_CM3
M4:ARM_MATH_CM4
H7:ARM_MATH_CM7
#include "arm_math.h"
#include "math.h"
#include "arm_const_structs.h"
#include "arm_const_structs.h"
如果cubemx生成的库没有,可以找板子的例程,将DSP的lib文件添加到工程中
/* USER CODE BEGIN PV */ uint8_t lcd_id[12]; //存放LCD ID字符串 float data = 0;//定义一个float型变量 float fft_inputbuf[FFT_LENGTH*2]; //FFT输入数组 float fft_outputbuf[FFT_LENGTH]; //FFT输出数组 /* USER CODE END PV */ /* USER CODE BEGIN 1 */ arm_cfft_radix4_instance_f32 scfft; uint8_t key,t=0; float time; uint8_t buf[50]; uint16_t i; char send[15]; /* USER CODE END 1 */ /* USER CODE BEGIN 2 */ LCD_Init(); POINT_COLOR=RED; //画笔颜色:红色 sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。 LCD_ShowString(30,40,210,24,24,"mcudev STM32F4"); LCD_ShowString(30,70,200,16,16,"TFTLCD TEST"); LCD_ShowString(30,90,200,16,16,"mcudev.taobao.com"); arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft结构体,设定FFT相关参数 /* USER CODE END 2 */ /* USER CODE BEGIN WHILE */ while (1) { data = arm_sin_f32(PI/6); //计算sin30° sprintf((char*)lcd_id,"LCD ID:%.5f",data);//0.49999 LCD_ShowString(30,110,200,16,16,lcd_id); for(i=0;i<FFT_LENGTH;i++)//生成信号序列 { fft_inputbuf[2*i]=100+ 10*arm_sin_f32(2*PI*i/FFT_LENGTH)+ 30*arm_sin_f32(2*PI*i*4/FFT_LENGTH)+ 50*arm_cos_f32(2*PI*i*8/FFT_LENGTH); //生成输入信号实部 //printf("%.2f\r\n",fft_inputbuf[2*i]); sprintf(send,"%.2f\r\n",fft_inputbuf[i*2]); HAL_UART_Transmit(&huart1,(uint8_t*)send,8,0xff); fft_inputbuf[2*i+1]=0;//虚部全部为0 } printf("\r\n"); arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4) printf("after:"); for(i=0;i<FFT_LENGTH;i++)//生成信号序列 { sprintf(send,"%.2f\r\n",fft_inputbuf[i*2]); HAL_UART_Transmit(&huart1,(uint8_t*)send,8,0xff); } arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把运算结果复数求模得幅值 printf("\r\n%d point FFT runtime:%0.3fms\r\n",FFT_LENGTH,time/1000); printf("FFT Result:\r\n"); for(i=0;i<FFT_LENGTH;i++) { printf("fft_outputbuf[%d]:%f\r\n",i,fft_outputbuf[i]); } /* USER CODE END WHILE */
如果没有LCD
/* USER CODE BEGIN PV */ float data = 0;//定义一个float型变量 float fft_inputbuf[FFT_LENGTH*2]; //FFT输入数组 float fft_outputbuf[FFT_LENGTH]; //FFT输出数组 /* USER CODE END PV */ /* USER CODE BEGIN 1 */ arm_cfft_radix4_instance_f32 scfft; uint8_t key,t=0; float time; uint8_t buf[50]; uint16_t i; char send[15]; /* USER CODE END 1 */ /* USER CODE BEGIN 2 */ arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft结构体,设定FFT相关参数 /* USER CODE END 2 */ /* USER CODE BEGIN WHILE */ while (1) { data = arm_sin_f32(PI/6); //计算sin30° //开调试看data值或串口输出 for(i=0;i<FFT_LENGTH;i++)//生成信号序列 { fft_inputbuf[2*i]=100+ 10*arm_sin_f32(2*PI*i/FFT_LENGTH)+ 30*arm_sin_f32(2*PI*i*4/FFT_LENGTH)+ 50*arm_cos_f32(2*PI*i*8/FFT_LENGTH); //生成输入信号实部 //printf("%.2f\r\n",fft_inputbuf[2*i]); sprintf(send,"%.2f\r\n",fft_inputbuf[i*2]); HAL_UART_Transmit(&huart1,(uint8_t*)send,8,0xff); fft_inputbuf[2*i+1]=0;//虚部全部为0 } printf("\r\n"); arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4) printf("after:"); for(i=0;i<FFT_LENGTH;i++)//生成信号序列 { sprintf(send,"%.2f\r\n",fft_inputbuf[i*2]); HAL_UART_Transmit(&huart1,(uint8_t*)send,8,0xff); } arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把运算结果复数求模得幅值 printf("\r\n%d point FFT runtime:%0.3fms\r\n",FFT_LENGTH,time/1000); printf("FFT Result:\r\n"); for(i=0;i<FFT_LENGTH;i++) { printf("fft_outputbuf[%d]:%f\r\n",i,fft_outputbuf[i]); } /* USER CODE END WHILE */
DMA点ADD添加,Circular模式
确认配置无误
输出频率为:168000000/168/5 = 200000Hz
/* USER CODE BEGIN 0 */
void SineWave_Data( uint16_t num,uint16_t *D,float U)
{
uint16_t i;
for( i=0;i<num;i++)
{
D[i]=(uint16_t)((U*sin(( 1.0*i/(num-1))*2*3.14159265358979)+U)*4095/3.3);
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 1 */
uint16_t Sine12bit[32] = {
2048 , 2460 , 2856 , 3218 , 3532 , 3786 , 3969 , 4072 ,
4093 , 4031 , 3887 , 3668 , 3382 , 3042 ,2661 , 2255 ,
1841 , 1435 , 1054 , 714 , 428 , 209 , 65 , 3 ,
24 , 127 , 310 , 564 , 878 , 1240 , 1636 , 2048
};
/* USER CODE END 1 */
//DAC
TIM2->ARR = 9; //修改ARR 可不加
HAL_TIM_Base_Start(&htim2); //打开定时器中断
//HAL_DAC_Start(&hdac,DAC_CHANNEL_1);
SineWave_Data(n,DualSine12bit,1.6); //产生正弦波函数
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *)Sine12bit, 32, DAC_ALIGN_12B_R);
#define fft_adc_n 1024 // 采1024个点
float adc_data[fft_adc_n*2]={0}; // 存ADC值
uint8_t ad_flag = 0;
HAL_TIM_Base_Start_IT(&htim3); //打开定时器3中断
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&adc_buffer,fft_adc_n); //ADC采集一组数据
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
ad_flag=1;
}
ADC中断,采集完成后标志位置1
while (1)
{
if(ad_flag == 1)
{
//数据处理
//......
ad_flag = 0; //标志位置0
}
}
float fft_in_adc_data[fft_adc_n*2]={0}; // FFT输入,实部是ADC值,虚部补0
float fft_out_adc_data[fft_adc_n]={0}; // FFT输出
uint16_t flag[fft_adc_n] = {0}; // 数据处理时暂时存放数据
int k = 1; // 找第k大值
float32_t maxValue = 0; // ADC最大值
uint32_t index = 0; // 最大值下标
int i,j;
float freq = 0; // 频率
arm_cfft_radix4_instance_f32 scfft; //FFT对应结构体变量
arm_cfft_radix4_init_f32(&scfft,fft_adc_n,0,1); //初始化scfft结构体,设置FFT相关参数
if(ad_flag == 1) { printf("finish\r\n"); ad_flag = 0; for(i=0;i<fft_adc_n;i++) { fft_in_adc_data[i*2] = adc_buffer[i]*3.3/4095; //实部 fft_in_adc_data[i*2+1] = 0; //虚部 } printf("\r\n"); arm_cfft_f32(&arm_cfft_sR_f32_len1024,fft_in_adc_data,0,1); arm_cmplx_mag_f32(fft_in_adc_data,fft_out_adc_data,fft_adc_n); fft_out_adc_data[0]/=1024; for(i=1;i<fft_adc_n;i++) fft_out_adc_data[i]/=512; for(i=0;i<fft_adc_n;i++) { printf("%.5f\t",fft_out_adc_data[i]); } printf("\r\n"); //arm_max_f32(&fft_out_adc_data[1],fft_adc_n/2-1,&maxValue,&index); /****查找最大值及其下标*********/ memset(flag, 0, sizeof(flag)); for (i = 1; i <= k; i++) { maxValue = 0.0; for (j = 1; j < fft_adc_n / 2; j++) { if (flag[j] == 1) break; if (fft_out_adc_data[j] > maxValue) { maxValue = fft_out_adc_data[j]; index = j; } } flag[index] = 1; } printf("index:%d\r\n",index); printf("Vmax:%.2f\r\n",maxValue); freq = (float)500000/fft_adc_n * (index) /2; //500000为采样率 printf("freq: %.3f",freq); ad_flag = 0; }
arm_cfft_sR_f32_len1024
在arm_const_structs.h
里面,如果报错,检查头文件arm_cfft_sR_f32_len1024
,如果采样512个点,则改为arm_cfft_sR_f32_len512
,以此类推fft_out_adc_data[0]
为直流分量电压值maxValue
为基波电压幅值fft_out_adc_data[0]
+maxValue
=正弦波最大值fft_out_adc_data[0]
-maxValue
=正弦波最小值https://blog.csdn.net/Nothing_To_Say_/article/details/123606260
https://blog.csdn.net/qq_34022877/article/details/123190943
https://blog.csdn.net/qq_24426625/article/details/129738537
等
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。