11.18作
17号开的会我才知道原来实验室软件的还有任务,就是那个FFT的那个任务了,这样拖着也不是个法(真是因为忘了),现在就把这个任务解决吧
那个任务我记不清了,我手机里也没有记录,好像是使用FFT算一下频谱吧,我个人认为这个任务的过程就
- 添加DSP库
- 定义所需的变量
- 正确的调用有关FFT变换的函数也就行了
下面进入正题
1.添加DSP库
勾选后点击OK,等待加载就行
加一个宏(图上面的),后面那个看自己,加或者不加都可以
再加俩H库,DSP库的添加就算完成了
2.定义所需的变量
#define FFT_LENGTH 1024
uint16_t adc_buff[200]; //存放ADC数据
AdcConvEnd 用来检测ADC是否采集完毕
0:没有采集完毕
1:采集完毕,在stm32f1xx_it里的DMA完成中断进行修改
__IO uint8_t AdcConvEnd = 0; //DMA的标志符号
uint16_t adcBuff[FFT_LENGTH]; //FFT的长度
float fft_inputbuf[FFT_LENGTH * 2]; //存放待进行FFT变换的数据
float fft_outputbuf[FFT_LENGTH]; //存放待FFT变换后的数据
就这几个了(至少调用最基本的FFT函数用以上这几个就够了)
3.正确的调用有关FFT变换的函数也就行了
下面是大概的代码了 (不是全部啊!像usart adc tim DMA 等等的基础配置还是要自己去配的)
/* USER CODE BEGIN 2 */
/**************** ADC采集部分 *********************************************************************/
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adcBuff, FFT_LENGTH);
HAL_TIM_Base_Start(&htim3);
while (!AdcConvEnd) //等待转换完毕
;
/****************进行傅里叶变换*********************************************************************/
for (int i = 0; i < FFT_LENGTH; i++) //存入缓存区
{
fft_inputbuf[i * 2] = adcBuff[i] * 3.3 / 4096;//实部赋值,* 3.3 / 4096是为了将ADC采集到的值转换成实际电压
fft_inputbuf[i * 2 + 1] = 0;//虚部赋值,固定为0.
}
arm_cfft_f32(&arm_cfft_sR_f32_len1024, fft_inputbuf, 0, 1);//傅里叶变换
arm_cmplx_mag_f32(fft_inputbuf, fft_outputbuf, FFT_LENGTH); //取模
/****************处理变换结果 *********************************************************************/
fft_outputbuf[0] /= 1024;
for (int i = 1; i < FFT_LENGTH; i++)//输出各次谐波幅值
{
fft_outputbuf[i] /= 512;
}
/****************打印结果*********************************************************************/
printf("FFT Result:\r\n");
for (int i = 0; i < FFT_LENGTH; i++)//输出各次谐波幅值
{
printf("%d:\t%.2f\r\n", i, fft_outputbuf[i]);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
具体fft的原理现在还没必要去完全了解,因为我们还没学像通信原理,高频等课程。为什么要算出频谱?频谱中的数据是什么?有什么用?等等的问题都无从解答,所以去了解fft的原理就没必要了
问题:
AdcConvEnd 用来检测ADC是否采集完毕
0:没有采集完毕
1:采集完毕,在stm32f1xx_it里的DMA完成中断进行修改
因为这个标志为的存在,此代码一次只能发一次数据。想要持续采集并发送FFT后的数据就要改代码(自己干)
到这应该就是圆满结束咯~~~~~~~~~~~~~~~~~~~~~~~~···~~
*