cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G070 ADC DMA - Invalid value in array.

Todg
Associate II

Hi.

I am using STM32G070RB.

I need to sequentially receive values from 5 channels using ADC DMA.

If normal circumstances, the ADC data of PA0 should be stored in Array[0] and the ADC data of PA1 should be stored in Array[1].

However, currently experiencing a bug where PB0's ADC data is stored in Array[0], and PA0's ADC data is stored in Array[1].

PB0's ADC data is a variable value, and the ADC data of other pins is a fixed value.

PB0's ADC data should come out with continuously changing values in the array[4].

Can you give me some advice where i made a mistake?

img1.png

img2.png

img3.pngimg4.pngimg5.png

 

main.c

 

void ADC_DMA_TC_Callback()
{
asm("nop");
}

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_ADC1_Init();
  MX_USART3_UART_Init();
  MX_TIM15_Init();
  MX_TIM16_Init();
  /* USER CODE BEGIN 2 */

   LL_ADC_StartCalibration(ADC1);
   while(LL_ADC_IsCalibrationOnGoing(ADC1));

   LL_DMAMUX_SetRequestID(DMAMUX1, LL_DMAMUX_CHANNEL_0, LL_DMAMUX_REQ_ADC1);
   LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
   LL_DMA_SetPeriphAddress(DMA1, LL_DMA_CHANNEL_1, LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA));
   LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)ADCVal);

   LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 5);
   LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
   LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);

   LL_ADC_Enable(ADC1);
   while (LL_ADC_IsActiveFlag_ADRDY(ADC1) == 0);
   //LL_TIM_EnableCounter(TIM15);
   LL_ADC_REG_StartConversion(ADC1);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

stm32g0xx_it.c

void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

	if(LL_DMA_IsActiveFlag_TC1(DMA1))
	{
		LL_DMA_ClearFlag_TC1(DMA1);
		ADC_DMA_TC_Callback();
	}
  /* USER CODE END DMA1_Channel1_IRQn 0 */

  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

  /* USER CODE END DMA1_Channel1_IRQn 1 */
}

 

1 ACCEPTED SOLUTION

Accepted Solutions
Piranha
Chief II

Most likely a problem because of ADC overrun. If it happens, it messes up the channel order. It can happen, for example, because of bus contention, but, while debugging, it basically happens all the time. You have to process it in the ADC interrupt by restarting the ADC channel sequence and DMA at the beginning.

View solution in original post

4 REPLIES 4
Piranha
Chief II

Most likely a problem because of ADC overrun. If it happens, it messes up the channel order. It can happen, for example, because of bus contention, but, while debugging, it basically happens all the time. You have to process it in the ADC interrupt by restarting the ADC channel sequence and DMA at the beginning.

Thank you for answer.

Pierre_Paris
ST Employee

Hello @Todg ,

Thank you for your question.

Q : Can you give me some advice where I made a mistake?

A : The mistake probably come from a bad initialization sequence. I downloaded your code and, indeed, I observed the one byte shift in the ADCVal array. (IN0 in Array[1], IN2 in Array[2], ...).

Copy this 2 lines :

   LL_ADC_StartCalibration(ADC1);
   while(LL_ADC_IsCalibrationOnGoing(ADC1));

And insert it between the labels (before the init):

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

 Best Regards,

Pierre

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Thank you!