STM32L0 ADC Interrumpir baja tasa de muestreo

2

Mi tasa de muestreo observada es mucho más baja de lo esperado y no puedo entender por qué.

Tengo la placa de descubrimiento STM32L053C6 Discovery y quiero usar el muestreo de ADC. Comencé desde el ejemplo STM32L053C8-Discovery / Illustrations / ADC / ADC_RegularConversion_Interrupt / from STM32CubeL0. En general, tengo la siguiente inicialización de ADC:

AdcHandle.Instance = ADC1;

AdcHandle.Init.OversamplingMode      = DISABLE;

AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV1;
AdcHandle.Init.LowPowerAutoPowerOff  = DISABLE;
AdcHandle.Init.LowPowerFrequencyMode = DISABLE;
AdcHandle.Init.LowPowerAutoWait      = DISABLE;

AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
AdcHandle.Init.SamplingTime          = ADC_SAMPLETIME_7CYCLES_5;
AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;
AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.ContinuousConvMode    = ENABLE;
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
AdcHandle.Init.DMAContinuousRequests = DISABLE;

/* Initialize ADC peripheral according to the passed parameters */
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
  Error_Handler();
}


/* ### - 2 - Start calibration ############################################ */
if (HAL_ADCEx_Calibration_Start(&AdcHandle, ADC_SINGLE_ENDED) != HAL_OK)
{
  Error_Handler();
}

/* ### - 3 - Channel configuration ######################################## */
/* Select Channel 0 to be converted */
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 0;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
  Error_Handler();
}

/* ### - 4 - Start conversion in Interrupt mode ########################### */
if (HAL_ADC_Start_IT(&AdcHandle) != HAL_OK)
{
  Error_Handler();
}

Y la llamada de vuelta como

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
  /* Get the converted value of regular channel */
  uwADCxConvertedValue = HAL_ADC_GetValue(AdcHandle);
  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4);
}

Tengo los relojes del sistema definidos como

static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  RCC_OscInitStruct.OscillatorType  = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState        = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLSource   = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLMUL      = RCC_PLL_MUL4;
  RCC_OscInitStruct.PLL.PLLDIV      = RCC_PLL_DIV2;
   if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource =  RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
}

Y el inicio de MSP como

void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
  GPIO_InitTypeDef                 GPIO_InitStruct;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO clock ****************************************/
  __HAL_RCC_GPIOA_CLK_ENABLE();
  /* ADC1 Periph clock enable */
  __HAL_RCC_ADC1_CLK_ENABLE();

  /*##- 2- Configure peripheral GPIO #########################################*/
  /* ADC3 Channel8 GPIO pin configuration */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*##-3- Configure the NVIC #################################################*/
  /* NVIC configuration for ADC EOC interrupt */
  HAL_NVIC_SetPriority(ADC1_COMP_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(ADC1_COMP_IRQn);
}

Con esa configuración, esperaría que el tiempo de conversión sea de aproximadamente 1.3µs. Sin embargo, el PB4 alterna cada 11µs. Lo que significa que obtengo una tasa de muestreo ligeramente superior a 80 kS / s.

El manual menciona tasas de muestreo por encima de 1MS / s. Estoy seguro de que me estoy perdiendo algo, pero no puedo ver lo que sería. ¿O debería usar los modos DMA para obtener tasas de muestreo más altas?

    
pregunta bilbo_pingouin

0 respuestas

Lea otras preguntas en las etiquetas