cancel
Showing results for 
Search instead for 
Did you mean: 

ADC encounters issues with continuous conversion using GPDMA

MECHO
Associate III

The board I am using is NUCLEO-H7S3 and I have encountered the following issues
I want to perform continuous and large data sampling using ADC+DMA, but when the collected value reaches 10000, the subsequent values become 0. When I modify the number of collected values to 50000, it stops at 17231 and the subsequent values remain 0. At this point, I am connecting the ADC pin to the 3.3V on the board. I'm not sure where the settings went wrong, please help me.
Thank you.

MECHO_0-1777792518463.pngMECHO_1-1777792548684.png

MECHO_5-1777792897527.png

 

MECHO_3-1777792847325.png

MECHO_2-1777792733760.png

MECHO_4-1777792869805.png

 

 

 

7 REPLIES 7
MM..1
Chief III

Seems your array is out of DMA access memory. You need more learning about RAM areas and DMA.

And dont insert images of code to forum, Instead use 

uint16_t ADCDATA1[200000];

and in linker script place it into riht region usw.

MECHO
Associate III

Thank you for your reply. I didn't understand what you were saying, but I noticed that the compiler assigned the address 0x2400008c to this array. Could you please provide a more detailed explanation.
My subsequent code will reply in the format you provided
Thanks

AScha.3
Super User

Hi,

but when the collected value reaches 10000, the subsequent values become 0

You start DMA here to get 10000 values , then wonder, why it stops at 10000 ?   :)

HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADCDATA1,10000);

+

>I want to perform continuous and large data sampling

So set the DMA to circular mode, on somewhat smaller array, to use the data in half-/full callbacks;

then you can get a continuous decoded (or whatever...) stream of data, as long as you let the DMA running.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you for your answer. I intended to collect 200000 data points, but DMA can only collect up to 65535 data points at a time. I originally planned to collect 200000 pieces of data first, and then have the computer analyze it, but it has been unable to accurately collect voltage. So I narrowed down the scope for analysis and discovered this problem. The above is my test code, and the problem is consistent with what I found before

/* USER CODE BEGIN PV */

int adcEnd = 0;
uint16_t ADCDATA1[200000];
int end = 0;
/* USER CODE END PV */
si5351aSetFrequency(968000000 , 0 );
  HAL_TIM_Base_Start_IT(&htim7);
  HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
  HAL_TIM_Base_Start(&htim6);
  HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADCDATA1,10000);
  int data;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    if(end == 1)
    {
      for (int i = 0; i < 200000; i++) 
      {
        data = 3300 * ADCDATA1[i] /4096;
        printf("%dmv-%d\r\n",data,i);
      }
      while (1)
      {
        ;
      }
    }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
  adcEnd++;
  if (adcEnd < 3) 
  {
    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADCDATA1[10000 * adcEnd], 10000);
  }
  else 
  {
    HAL_ADC_Stop(&hadc1);
    end = 1;
  }
  
}

Did you enable the callback ?

AScha3_0-1777808826021.png

Just set a breakpoint in the callback, to see its called .

+

Why not on circular mode ? Is the standard way, for continuous data stream.

 

If you feel a post has answered your question, please click "Accept as Solution".

Thank you for your reply. It is also possible to use the default callback function, but I don't think there is a need to use it separately. On the other hand, I used circular mode, which you can see from my project and also from the previous screenshots. I just tried this feature, but it doesn't seem to solve the problem.

If you config circullar then never you can call twice

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADCDATA1[10000 * adcEnd], 10000);

without stop previous DMA.

Next point is GPDMA have linked lists and can store more as 65536 with use it.
And ofcourse is perfectly normal have 0 on 10000 position, because it continue on start circullary.

But back to real trouble, 17231 stop may have more source, but primary is OVR (overrun DMA) on bus.

Next is as i write RAM areas. Your MCU have for example 600kB RAM, but not all parts is DMA usable. You must read pdf and use desired area for desired functions. And too 200000 u16 is 400kB, but maybe only 320kB on your MCU is ok area for DMA etc.