cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411 multi-channel DMA + software trigger, VREFINT VBAT two can not collect at the same time

colorhacker
Visitor

After using cubemx, I tested the single channel round-robin acquisition and there was no problem.
After changing to DMA acquisition, as long as VREFINT and VBAT exist at the same time, the data of the first channel is wrong. The following is the correct code:

uint16_t data[256]; 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
}
int main{
...
...
while(1){
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)data, hadc1.Init.NbrOfConversion*2);
printf("adc: %d %d %d %d %d %d \n",data[0],data[1],data[2],data[3],data[4],data[5]);
HAL_Delay(1000);
}
}
static void
MX_ADC1_Init(void)
{

/* USER CODE BEGIN ADC1_Init 0 */

/* USER CODE END ADC1_Init 0 */

ADC_ChannelConfTypeDef sConfig = {0};

/* USER CODE BEGIN ADC1_Init 1 */

/* USER CODE END ADC1_Init 1 */

/** 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_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 2;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}

/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
// sConfig.Channel = ADC_CHANNEL_VBAT;
// sConfig.Rank = 2;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
// {
// Error_Handler();
// }

/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */

/* USER CODE END ADC1_Init 2 */

}
correct result:
adc:1497 378 1497 382 0 0
adc:1497 378 1498 382 0 0
adc:1497 377 1497 381 0 0
adc:1497 378 1498 382 0 0
adc:1497 378 1497 382 0 0

The following is the error code:

 

uint16_t data[256]; 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
}
int main{
...
...
while(1){
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)data, hadc1.Init.NbrOfConversion*2);
printf("adc: %d %d %d %d %d %d \n",data[0],data[1],data[2],data[3],data[4],data[5]);
HAL_Delay(1000);
}
}
static void
MX_ADC1_Init(void)
{

/* USER CODE BEGIN ADC1_Init 0 */

/* USER CODE END ADC1_Init 0 */

ADC_ChannelConfTypeDef sConfig = {0};

/* USER CODE BEGIN ADC1_Init 1 */

/* USER CODE END ADC1_Init 1 */

/** 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_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 2;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}

/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_VBAT;
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}

/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
// sConfig.Channel = ADC_CHANNEL_0;
// sConfig.Rank = 2;
// if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
// {
// Error_Handler();
// }
/* USER CODE BEGIN ADC1_Init 2 */

/* USER CODE END ADC1_Init 2 */
}
error result:
adc: 10 919 10 920 0 0
adc: 10 920 10 919 0 0
adc: 11 919 10 920 0 0
adc: 10 919 10 919 0 0
adc: 11 919 10 919 0 0
adc: 11 919 9 919 0 0
adc: 11 920 10 919 0 0


The only difference above is whether Vbat and channel 0 are turned on or not. I have no idea why the number of the first channel is around 10. I tested it for a long time and finally found the smallest error code. Please help me check it. Thank you.

 

 

0 REPLIES 0