打印
[应用相关]

STM32F3做FFT算出频率和实际有偏差

[复制链接]
4520|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mm7989680|  楼主 | 2016-11-2 11:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32F303的ADC采样后做FFT算频率,ADC时钟72M,采样间隔74个ADC cycles,采样频率约972.972K,大于那奎斯特采样要求,采样数量1024个点,信号源信号频率200K,3.00Vpp,offset1.65Vdc,实际算出来频率190033.593750,为什么FFT结果差了约10K,而且采样频率越低,算出来的准确度还高些,高了反而差距大?


int main(void)
{


  /* USER CODE BEGIN 1 */


  /* USER CODE END 1 */


  /* MCU Configuration----------------------------------------------------------*/


  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();


  /* Configure the system clock */
  SystemClock_Config();


  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_DAC1_Init();
  MX_TIM2_Init();
  MX_ADC1_Init();
  MX_TIM3_Init();
  MX_USART2_UART_Init();


  /* USER CODE BEGIN 2 */
       
        HAL_TIM_Base_Start(&htim2);
        HAL_TIM_Base_Start(&htim3);
////        HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0);
////        HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1,(uint32_t*) Sine, 32, DAC_ALIGN_12B_R);
       
        HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
        HAL_ADC_Start_DMA(&hadc1, (uint32_t*) ReadData, Num);
       
////        HAL_ADC_Stop_DMA(&hadc1);
//        HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*) ReadData, Num, DAC_ALIGN_8B_R);
       
//        HAL_UART_Transmit_DMA(&huart2, (uint8_t*) ReadData, Num);
//        HAL_UART_Transmit(&huart2, 0x11, 1, 0xFFFF);
//        printf("\r\nADC was Down!\r\n");


        for(int i=0;i<Num;i++)
        {
                ADC_ConvertedValue[2*i]=(float)(ReadData&0xFF)*3.3/256;                                        //将ADC取到的值转化为0-3.3的电压值,为实部
                ADC_ConvertedValue[2*i+1]=0;                                                                                                                                                                //虚部为0
        }
       
//        for(int i=0;i<Num;i++)
//        {
//                ADC_ConvertedValue[2*i]=(float)(ReadData&0xFF);                                        //将ADC取到的值转化为0-3.3的电压值,为实部
//                ADC_ConvertedValue[2*i+1]=0;                                                                                                                                                                //虚部为0
//        }


        arm_cfft_f32(&arm_cfft_sR_f32_len1024, ADC_ConvertedValue, ifftFlag, doBitReverse);
       
        arm_cmplx_mag_f32(ADC_ConvertedValue, testOutput, Num);


        for(uint32_t i=0;i<Num;i++)
        {
                printf("fft_outputbuf[%d]:%f\r\n",i,testOutput);
        }
        testOutput[0]=0;
  /* Calculates maxValue and returns corresponding BIN value */
  arm_max_f32(testOutput, Num/2, &maxValue, &testIndex);
       
        Frequence = (((float32_t)testIndex+1)/(float32_t)Num)*(72000000/74);


        printf("maxValue is %f\r,corresponding BIN value is %d\r,frequence is %f\r\n",maxValue,testIndex,Frequence);


  /* USER CODE END 2 */


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */




  while (1)
  {
  /* USER CODE END WHILE */


  /* USER CODE BEGIN 3 */


               
  }
  /* USER CODE END 3 */


}


沙发
mm7989680|  楼主 | 2016-11-3 16:42 | 只看该作者
ADC   8bit改到12bit准确度一下子提高了  现在基本只差2K了,信号源幅度降到100mV也很准,什么原因?按理位数变化影响不会这么大

使用特权

评论回复
板凳
nstel| | 2016-11-3 17:12 | 只看该作者
ADC的采样电路有没有问题呢?

使用特权

评论回复
地板
icecut| | 2016-11-3 18:26 | 只看该作者
你先看看你踩到的值是不是对的.或者说看看直流分量是不是正常.

使用特权

评论回复
5
mm7989680|  楼主 | 2016-11-3 19:57 | 只看该作者
nstel 发表于 2016-11-3 17:12
ADC的采样电路有没有问题呢?

ADC用的是STAM32内置的

使用特权

评论回复
6
wangguanfu| | 2016-11-4 08:28 | 只看该作者
能整工程打包

使用特权

评论回复
7
wangguanfu| | 2016-11-4 08:28 | 只看该作者
能整个工程打包上来?

使用特权

评论回复
8
shalixli| | 2016-11-4 08:47 | 只看该作者
FFT 如何计算频率 ?  好像 FFT不是用来计算频率的吧, FFT是把频域 转 时域的。

因此  楼主 的  基本原理 都没有弄清楚!  大错特错!

使用特权

评论回复
9
mm7989680|  楼主 | 2016-11-7 18:48 | 只看该作者
shalixli 发表于 2016-11-4 08:47
FFT 如何计算频率 ?  好像 FFT不是用来计算频率的吧, FFT是把频域 转 时域的。

因此  楼主 的  基本原理 ...

呵呵

使用特权

评论回复
10
xxzouzhichao| | 2016-11-8 08:31 | 只看该作者
采样率得是被测频率的4/8/16/32……倍才能计算精确,否则会有频谱泄露,如果能满足整数倍,那就用dft

使用特权

评论回复
11
小曾1220| | 2016-11-8 13:44 | 只看该作者

使用特权

评论回复
12
sl_168| | 2016-11-8 16:50 | 只看该作者
时钟及采样点的误差引起的。

使用特权

评论回复
13
shalixli| | 2016-11-8 17:48 | 只看该作者
本帖最后由 shalixli 于 2016-11-8 18:16 编辑

楼主真是很傻很天真。
FFT的结果   就是频域的 模。 就是你的采样率 FS 扯蛋的关系。 这个是理论的扯蛋关系, 实际的中断,ADC保持,转换时间。。。。。够你TMD从扯蛋的。

因此,用FFT方法计算频率的人,都是很傻很天真的 小学生。
你的公式 死定的就是   2/1024 *  FS

这里 你 测量出真正的FS频率。就不会有什么误差。 这个靠测量,而你的参数是72MHZ  74个ADC 设置,按理想计算的就是 那个FS,
因此 计算出来就是 190K,  

呵呵。 真实的FS是多少? 你可以反推算出来的, 因为你知道你的信号是200KHZ,

但是如果你不知道,不确定你的信号是多少情况下呢?我问你,如何计算?


使用特权

评论回复
14
fxmxh_| | 2016-11-9 08:43 | 只看该作者
楼猪,现在弄啥成了?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

112

主题

371

帖子

4

粉丝