# STMF4 ADC conversion seems slow

I'm using an STM32F4 to do some 12 bit conversions. I see from here that I should have hopes of getting somewhere around 1us per conversion, and since I'm doing 2 conversions, I would expect somewhere around 2us to get both channels.

However, I'm seeing from a rise and fall of a GPIO that I'm setting so I can time this whole process on a scope that I'm coming in at around 4.6us., which is over twice as long as I expected.

What I really want is a real fast sample of two OpAmp outputs at the top of a center aligned PWM to feed a FOC motor controller, so the faster and more sychronous, the better. I need to kick off the conversion at the same time, but I also need to be sure that the sample completed, AND the DMA transfered the data to an array in RAM before I do any calculations based on their value.

I had originally used the ADC in continuous conversion mode, but that messed up my timers pretty bad and caused a lot of pulses to be missed, so I've resorted to just sampling when I need it, namely after a capture compare event...But this conversion is taking tooooo long.

void MX_ADC1_Init(void)
{

/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
{
_Error_Handler(__FILE__, __LINE__);
}

/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Rank = 1;
{
_Error_Handler(__FILE__, __LINE__);
}

/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Rank = 2;
{
_Error_Handler(__FILE__, __LINE__);
}

}


Here's my DMA

void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();

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

}

{

GPIO_InitTypeDef GPIO_InitStruct;
{
/* USER CODE BEGIN ADC1_MspInit 0 */

/* USER CODE END ADC1_MspInit 0 */

*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

{
_Error_Handler(__FILE__, __LINE__);
}

/* USER CODE BEGIN ADC1_MspInit 1 */

/* USER CODE END ADC1_MspInit 1 */
}
}


And, finally, here's how I'm measuring this time:

void Feedback_Controller(void){

HAL_GPIO_WritePin(GPIOB, SAMP_Pin, SET);

//HAL_GPIO_WritePin(GPIOA, SAMP_Pin, RESET);
}

HAL_GPIO_WritePin(GPIOB, SAMP_Pin, RESET);
}


And here's how things get initialized in main:

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 */

/* 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_DMA_Init();
MX_TIM1_Init();

/* USER CODE BEGIN 2 */

HAL_TIM_Base_Start(&htim1);
HAL_TIM_Base_Start_IT(&htim1);
HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_2);
HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_3);
HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_4);
/* USER CODE END 2 */

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

/* USER CODE BEGIN 3 */

}
/* USER CODE END 3 */

}

• Have you thought about using the capture event as a trigger to the ADC conversion start? I'm not sure if that is possible on your device, but I used the timers before as triggers. I'm not sure which frequency the controller is running, but a HAL can add a significant overhead. – Arsenal Jan 25 '18 at 16:21
• The sampling time for a single sample cannot generally be used to define the sample throughput rate - the throughput will always be slower than simply adding up conversion times if software configuration is necessary; even bare metal control of the conversion will add some overhead and as Arsenal notes, a hardware abstraction layer (almost by definition) will add significant timing overhead. – Peter Smith Jan 25 '18 at 16:28