2026-04-24 2:13 AM - last edited on 2026-04-24 2:57 AM by mƎALLEm
Hello,
I am working on an STM32F7 project where I need to sample multiple ADC peripherals using DMA triggered by a timer.
Problem: No ADC data is being written to ADC_BUF or ADC3_BUF even though main loop runs (buffers ADC_BUF and ADC3_BUF remains zero while counter increases)
Current Setup:
ADC1: 1 Channel, DMA2 Stream 0, triggered by TIM2 TRGO UPDATE
ADC3: 2 Channels, DMA2 Stream 1, triggered by TIM2 CC2
DMA: Circular mode, DMAContinuousRequests enabled
TIM2: 10 Hz update event
Mode: ContinuousConvMode is Disabled, ScanConvMode is Enabled
What do I need to change to fix this?
/* USER CODE BEGIN PV */
volatile uint16_t ADC_BUF[ADC_BUF_LEN];
volatile uint16_t ADC3_BUF[ADC_BUF_LEN];
uint16_t counter = 0;
/* USER CODE BEGIN PV */
/* USER CODE BEGIN 2 */
HAL_CAN_Start(&hcan1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_BUF, ADC_BUF_LEN);
HAL_ADC_Start_DMA(&hadc3, (uint32_t*)ADC3_BUF, ADC_BUF_LEN);
HAL_TIM_Base_Start(&htim2);
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6);
HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_7);
}
/* USER CODE END 4 */
// ADC1 Settings
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = ENABLE;
// ADC3 Settings
hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc3.Init.Resolution = ADC_RESOLUTION_12B;
hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc3.Init.ContinuousConvMode = DISABLE;
hadc3.Init.DiscontinuousConvMode = DISABLE;
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_CC2;
hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc3.Init.NbrOfConversion = 2;
hadc3.Init.DMAContinuousRequests = ENABLE;
// TIM2 Settings
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7200-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 1000-1;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
I'm new to stm32 so please let me know if you need any additional information! Any insights to get my buffers working would be greatly appreciated!
2026-04-24 7:00 AM
Hello @M_Vance88
I would suggest first testing with only one ADC + one DMA + one timer trigger to make sure the basic acquisition chain is working correctly. Once you confirm that a single ADC is filling its buffer properly, you can then add the second ADC and its trigger step by step.
You can also refer to the following example as a starting point for a timer-triggered ADC with DMA configuration:
https://github.com/STMicroelectronics/STM32CubeWB/tree/master/Projects/P-NUCLEO-WB55.Nucleo/Examples/ADC/ADC_SingleConversion_TriggerTimer_DMA