AnsweredAssumed Answered

ADC triggering with timers and using DMA

Question asked by Omar Suárez on Feb 28, 2018
Latest reply on Mar 1, 2018 by Omar Suárez

Hi everyone,


I need to control the ADC in a STM32F769 MCU to take a bunch of samples after a period of time (this acquisition is repeated over time). My idea is to use one timer as a counter and as master controller of another timer. This second timer would be configured as One-shot so it can take x samples (x One-shot times). Each one-shot should then trigger the ADC and at the end of conversion the DMA would have to take the sample and put it in a buffer in the memory automatically.

To give an intuition of this previously description I attach a pdf with a schematic of what I want to do.


I have made some tests trying to configure one timer as a counter to trigger the ADC and also the DMA but unfortunately It doesn't seem to work properly. The DMA seems to work only the first time but no after the first triggering. I am not sure what I am doing wrong.


I am also wondering whether this is the best way to take samples from an ADC.


This is the configuration of the peripherals used for the tests (using only one timer as up counter):


/* ADC1 init function */
static void MX_ADC1_Init(void)

  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T6_TRGO;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
    _Error_Handler(__FILE__, __LINE__);

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
    _Error_Handler(__FILE__, __LINE__);



/* TIM6 ------------------------------------------------------------------------------- */

/* TIM6 init function */
static void MX_TIM6_Init(void)

  TIM_MasterConfigTypeDef sMasterConfig;

  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 12000;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 5000;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
    _Error_Handler(__FILE__, __LINE__);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
    _Error_Handler(__FILE__, __LINE__);



/* DMA ----------------------------------------------------------------- */

  * Enable DMA controller clock
static void MX_DMA_Init(void)
  /* DMA controller clock enable */

  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);




/* MAIN FUNCTION -------------------------------------------------------------------------------------------------------------------------- */


int main(void)

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

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  /* Configure the system clock */

  /* Initialize all configured peripherals */

  /* init the ADC DMA conversion */
  HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADCreadings, 1);

  /* Init the timer for triggering the ADC */

  while (1)



Thanks in advanced,