Home > Software engineering >  The adc should be able to work well for this kind of applications?
The adc should be able to work well for this kind of applications?

Time:03-21

I've been trying to process speech on a stm32f407ve development board for some time now, which makes me wonder if the ADC is really set up to precisely sample the values. CMSIS FFT Functions. But when I try to couple it with the ADC in continuous conversion to sample a sine signal, it doesn't seem to sample well periodically. I put a sine signal into it from a frequency test of a 1khz sine wave from an internet video with a plug that I take out of some headphones, which by the way I already tested that it works correctly with an oscilloscope. So... this one from the development board is obviously not from a DSP but its ADC should work correctly for this type of application? Here is my code, obviously I made sure that the test was emitting voltage before the debug.

#include "main.h"
#include "arm_math.h"
#include "arm_const_structs.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define Fs 4096;
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;

/* USER CODE BEGIN PV */

#define SIGNAL_BUFFER_LENGTH 4096
float signalBuffer[2*SIGNAL_BUFFER_LENGTH];
float fftBuffer[2*SIGNAL_BUFFER_LENGTH];
float magnitudes[SIGNAL_BUFFER_LENGTH];


/* USER CODE END PV */
uint32_t k;
uint32_t cont1,cont2;

uint32_t start;
uint32_t stopi;
uint32_t delta;

float32_t maxValue;             /* Max FFT value is stored here */
uint32_t maxIndex;
float frecuencia=10.0;
float32_t Ts;
float tiempo;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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();

  /* USER CODE BEGIN Init */
#define ARM_CM_DEMCR (*(uint32_t*)0xE000EDFC)
#define ARM_CM_DWT_CTRL (*(uint32_t*)0xE0001000)
#define ARM_CM_DWT_CYCCNT (*(uint32_t*)0xE0001004)

  if(ARM_CM_DWT_CTRL !=0){

      ARM_CM_DEMCR  |= 1<<24;
      ARM_CM_DWT_CYCCNT =0;
      ARM_CM_DWT_CTRL  |= 1<<0;


  }

  /* 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_ADC1_Init();
  /* USER CODE BEGIN 2 */
  Ts=1.0/(float)Fs;


  HAL_ADC_Start(&hadc1);
  for(k=0;k<2*SIGNAL_BUFFER_LENGTH;k =2 )
  {
      signalBuffer[k]=HAL_ADC_GetValue(&hadc1);


  }
  k  ;
  //signalBuffer[0]=0;
 //start= ARM_CM_DWT_CYCCNT;
  arm_cfft_f32(&arm_cfft_sR_f32_len4096,signalBuffer,0,1);
  signalBuffer[0]=0;
  arm_cmplx_mag_f32(signalBuffer,magnitudes,4096);
  arm_max_f32(magnitudes, 4096, &maxValue, &maxIndex);
  //stopi = ARM_CM_DWT_CYCCNT;
  //delta=stopi-start;

  //tiempo=delta/8.0E07*1000.0;
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

CodePudding user response:

You are just calling the function to take a single reading over and over in a loop. There is no reason to think that each pass through this loop will take the same amount of time. You need to set the ADC to be triggered from a timer in order to have some kind of reproducible sample rate.

In general the internal ADC is not of suitable quality for audio use. There is an external audio codec fitted to this board, look at the example projects in the Stm32CubeF4 package.

  • Related