OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5454|回复: 4

STM32F7 adc+tim+dma 进行FFT计算的问题

[复制链接]

6

主题

23

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2021-6-19
在线时间
67 小时
发表于 2021-10-20 14:46:31 | 显示全部楼层 |阅读模式
15金钱
大家好!想请教一下大家。我在使用DSP库进行FFT处理风速传感器的波形信号。代码如下:
ADC+DMA:
  1. ADC_ChannelConfTypeDef hadc2_channel;
  2. void MY_ADC_Init(void)
  3. {
  4.     __HAL_RCC_DMA2_CLK_ENABLE();

  5.     hdma_adc2.Instance = DMA2_Stream2;
  6.     hdma_adc2.Init.Channel = DMA_CHANNEL_1;
  7.     hdma_adc2.Init.Direction = DMA_PERIPH_TO_MEMORY;
  8.     hdma_adc2.Init.PeriphInc = DMA_PINC_DISABLE;               //???????
  9.     hdma_adc2.Init.MemInc = DMA_MINC_ENABLE;                   //???????
  10.     hdma_adc2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;  //??????:16?
  11.     hdma_adc2.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;     //???????:16?
  12.     hdma_adc2.Init.Mode = DMA_CIRCULAR;                          //???????
  13.     hdma_adc2.Init.Priority = DMA_PRIORITY_LOW;             //?????
  14.     hdma_adc2.Init.FIFOMode = DMA_FIFOMODE_DISABLE;            /* ??FIFO*/

  15.     HAL_DMA_Init(&hdma_adc2);

  16.     __HAL_LINKDMA(&hadc2, DMA_Handle, hdma_adc2);                //?DMA?ADC????


  17.     hadc2.Instance = ADC2;
  18.     hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //4??,ADCCLK=PCLK2/4=108/4=27MHZ
  19.     hadc2.Init.Resolution = ADC_RESOLUTION_12B;           //12???
  20.     hadc2.Init.ScanConvMode = DISABLE;                    //?????
  21.     hadc2.Init.ContinuousConvMode = DISABLE;              //??????
  22.     hadc2.Init.DiscontinuousConvMode = DISABLE;           //?????????
  23.     hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; //??????
  24.     hadc2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_CC2;     //????
  25.     hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;           //???
  26.     hadc2.Init.NbrOfConversion = 1;                       //1????????? ??????????1
  27.     hadc2.Init.DMAContinuousRequests = ENABLE;           //??DMA??
  28.     hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  29.     HAL_ADC_Init(&hadc2);

  30.     hadc2_channel.Channel = ADC_CHANNEL_3;                                 //??
  31.     hadc2_channel.Rank = 1;                                     //??1
  32.     hadc2_channel.SamplingTime = ADC_SAMPLETIME_3CYCLES;      //????
  33.     hadc2_channel.Offset = 0;
  34.     HAL_ADC_ConfigChannel(&hadc2, &hadc2_channel);       //????
  35.                
  36. }
复制代码
TIM:
  1. TIM_HandleTypeDef htim2;
  2. TIM_OC_InitTypeDef TIM2_CH2Handler;
  3. void MY_TIM2_Init(void)
  4. {
  5.     __HAL_RCC_TIM2_CLK_ENABLE();
  6.        


  7.     htim2.Instance = TIM2;
  8.     htim2.Init.Prescaler = 108-1;
  9.     htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  10.     htim2.Init.Period = 100;
  11.     htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  12.     HAL_TIM_PWM_Init(&htim2);


  13.     TIM2_CH2Handler.OCMode = TIM_OCMODE_PWM1;
  14.     TIM2_CH2Handler.Pulse = 50;
  15.     TIM2_CH2Handler.OCPolarity = TIM_OCPOLARITY_LOW;
  16.     TIM2_CH2Handler.OCFastMode = TIM_OCFAST_DISABLE;
  17.     HAL_TIM_PWM_ConfigChannel(&htim2, &TIM2_CH2Handler, TIM_CHANNEL_2) ;

  18.     TIM_CCxChannelCmd(htim2.Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
  19.     __HAL_TIM_ENABLE(&htim2);
  20.                 //__HAL_TIM_DISABLE(&htim2);
  21. }
复制代码
FFT:
  1. uint16_t FFT_ADC(uint16_t* buffer)
  2. {
  3.         uint16_t index;
  4.         for(int j=0;j<COUNT;j++)
  5.         {
  6.                 FFT_IN_Buffer[2*j] = buffer[j];            //实部//
  7.                 FFT_IN_Buffer[2*j+1] = 0;                      //虚部为0//
  8.         }
  9.         arm_cfft_f32(&arm_cfft_sR_f32_len1024,FFT_IN_Buffer,0,1);           //1024点FFT//
  10.         arm_cmplx_mag_f32(FFT_IN_Buffer,FFT_OUT_Buffer,COUNT);              //复数模平方,算幅值//
  11. //        printf("FFT result is:\r\n");
  12. //        for (int i = 0; i < COUNT; i++)
  13. //  {
  14. //        if (i % 8 == 0) printf("\r\n");
  15. //        printf("%.1f  ", FFT_OUT_Buffer[i]);
  16. //        }
  17.         index = Max_Index(FFT_OUT_Buffer,COUNT);
  18. //        printf("\r\n****************************************************************\r\n");
  19.         return index;
  20. }

  21. //找出频率最大值对应的下标//
  22. uint16_t Max_Index(float* buffer,int N)
  23. {
  24.         float Max = buffer[1];
  25.         uint16_t index = 1;
  26.         for(int i=2;i<N;i++)
  27.         {
  28.                 if(Max<buffer[i])
  29.                 {
  30.                         Max = buffer[i];
  31.                         index = i;
  32.                 }
  33.         }
  34.         return index;
  35. }
复制代码
主程序中
  1. int main()
  2. {
  3.            MY_ADC_Init();
  4.         MY_TIM2_Init();
  5.         HAL_ADC_Start_DMA(&hadc2, (uint32_t *)ADC2_Buffer, sizeof(ADC2_Buffer));
  6.                 uint16_t index;
  7.         int Frequency =0;
  8.          while(1)
  9.          {
  10.                                               index = FFT_ADC(ADC2_Buffer);
  11.                                 Frequency = (Fs/COUNT)*index;
  12.                                 printf("%d\r\n", Frequency);
  13.           }
  14. }
复制代码
我通过调试 观察发现FFT_IN的数组,奇数下标(对应虚部)并没有被赋值为0(如图1)
FFT计算出来的频率也有些不对劲(图2)。请问一下是哪个环节出现了纰漏。谢谢!

图1

图1
FFT_OUT.jpg
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

890

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1477
金钱
1477
注册时间
2020-8-19
在线时间
335 小时
发表于 2021-10-21 09:44:45 | 显示全部楼层
回复

使用道具 举报

6

主题

23

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2021-6-19
在线时间
67 小时
 楼主| 发表于 2021-10-21 09:50:11 | 显示全部楼层

谢谢大佬
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2022-1-21
在线时间
1 小时
发表于 2022-1-21 12:30:34 | 显示全部楼层
DMA装满后,停掉DMA和定时器,将数据进行FFT后打开DMAHE 定时器
回复

使用道具 举报

10

主题

212

帖子

0

精华

高级会员

Rank: 4

积分
735
金钱
735
注册时间
2019-4-8
在线时间
224 小时
发表于 2022-2-11 11:47:02 | 显示全部楼层
请问 最后搞定了没 如果要测相位 怎样测呢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 03:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表