基于stm32f103c8采集音频信号进行FFT频谱显示不成功,向各位...

2019-12-25 18:50发布

本帖最后由 eyancool 于 2017-8-17 11:10 编辑

自从在网上看到DIY音乐频谱显示后,就想着自己折腾一块板,现在板子已经打样回来,并手工焊好.接上OLED也能正常工作,在论坛找了好多资料之后,用CUBE MX照着写了一个程序,也不知道行不行得通.如果采集到信号并FFT转换后,如何在OLED显示音柱?因为只有初中文化水平,对FFT没有任何认识.还请大家耐心指点一下.谢谢了.以下是主要的代码,请大神帮忙瞅瞅.
ADC部分初始化
/* ADC1 init function */
static void MX_ADC1_Init(void)
{

  ADC_ChannelConfTypeDef sConfig;

    /**Common config
    */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure Regular Channel
    */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

TIMER3 初始化部分
/* TIM3 init function */
static void MX_TIM3_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 71;   //71分频后  得到1MHZ的频率
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 24;      //40K的采样频率
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

//-------------------------------------------------------------------------
//取模程序
//-------------------------------------------------------------------------

void powerMag(uint32_t nfill)
{
  int32_t lX,lY;
  uint32_t i;

  for (i=0; i < nfill; i++)
  {
    lX= (lBUFOUT<<16)>>16; /* sine_cosine --> cos */
    lY= (lBUFOUT >> 16);   /* sine_cosine --> sin */   
    {
      float X=  64*((float)lX)/32768;
      float Y = 64*((float)lY)/32768;
      float Mag = sqrt(X*X+ Y*Y)/nfill;                 // 先平方和,再开方
      lBUFMAG = (uint32_t)(Mag*65536);                 //
    }   
  }
}

int main(void)
{

  /* USER CODE BEGIN 1 */
  uint8_t i;
  /* USER CODE END 1 */

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

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

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

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

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  MX_ADC1_Init();

  /* Initialize interrupts */
  MX_NVIC_Init();

  /* USER CODE BEGIN 2 */
        HAL_TIM_Base_Start_IT(&htim3 );
          HAL_ADC_Start(&hadc1);
                HAL_ADC_Start_IT(&hadc1);
                OLED_Init() ;                        //初始化OLED  
                OLED_Clear();
                HAL_Delay(2000);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
               
        if(Value)     //采集64点信号完成标志
        {
                cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);          //FFT计算
                powerMag(NPT);                                         //取模
               
                        for(i=0;i<NPT;i++)       //这是在OLED上显示采集到的ADC数据和取模后的数据
                {
                HAL_Delay(100);
                OLED_ShowNum(0,0,ADC_Value,12,16);       
                OLED_ShowNum(0,2,lBUFIN,12,16);
                OLED_ShowNum(0,4,i,4,16);
                OLED_ShowNum(0,6,lBUFMAG,8,16);
                }
                HAL_ADC_Start(&hadc1);
                HAL_ADC_Start_IT(&hadc1);
                value=0;
                Value=0;
                HAL_TIM_Base_Start_IT(&htim3 );
        }

  }

以下是TIMER中断和ADC中断
/**********  定时器中断入口   ***********/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
       
                if(htim==&htim3)  //
                        {
                                ADC_Value[value]=ADC_ConvertedValue;
                                lBUFIN[value]=ADC_ConvertedValue<<16;
                                if(value<NPT)
                                {
                                value++;
                                HAL_ADC_Start(&hadc1);
                                HAL_ADC_Start_IT(&hadc1);
                                }
                                else
                                {
                                        HAL_TIM_Base_Stop_IT(&htim3 );
                                        Value=1;
                                }
                               
                                //HAL_ADC_Start(&hadc1);
                                //HAL_ADC_Start_IT(&hadc1);
                        }
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
                ADC_ConvertedValue=HAL_ADC_GetValue(&hadc1);
                HAL_ADC_Stop(&hadc1);
                HAL_ADC_Stop_IT(&hadc1);
}  


附件是网上找的原理图和MDK工程文件.
0条回答

一周热门 更多>