cancel
Showing results for 
Search instead for 
Did you mean: 

Strange points at ADC from STM32F407

Andrey Vieira
Associate II
Posted on April 22, 2017 at 16:17

Hi, I am trying to use ADC with DMA on the STM32F407 in two channels (PA1 and PA2), so, basically I created the project using CubeMX, exported it to Coocox, ran the debug to fill the vector  and imported these points from Matlab to see the signal wave.

The signal that I�m taking is from the electrical network (127 VAC/60 Hz), attenuated by a transformer and a resistor divider, and added a bias through another resistor divider and a capacitor.

The problem is showed in the image below, where appears something like a discontinuous point, and its occurs in different times of the wave:

0690X00000606q2QAA.png

                                               Voltage Wave (V Vector)

I have changed the settings of ADC and DMA many times but no success.

I will put the mainly code if you need the whole code just me know.

&sharpdefine Length 256

uint32_t Amostras[2*Length]; //Vector to Samples

uint32_t V[Length]; //Voltage samples

uint32_t I[Length]; // Current samples

int main(void)

{ /* USER CODE BEGIN 1 */

    int i =0;

   HAL_ADC_Start_DMA(&hadc1, Amostras, 512);

while (1)

  { //4095 = 2.92 V

     i=0;

            while(i<Length){

                V[i] = Amostras[2*i];

                I[i] =  Amostras[(2*i)+1];

                i++;

            }

}

void MX_ADC1_Init(void)

{

  ADC_ChannelConfTypeDef sConfig;

    /**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 = ENABLE;

  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_SINGLE_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_1;

  sConfig.Rank = 1;

  sConfig.SamplingTime = ADC_SAMPLETIME_112CYCLES;

  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_2;

  sConfig.Rank = 2;

  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

  {

    Error_Handler();

  }

}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)

{

  GPIO_InitTypeDef GPIO_InitStruct;

  if(adcHandle->Instance==ADC1)

  {

  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */

    /* Peripheral clock enable */

    __HAL_RCC_ADC1_CLK_ENABLE();

 

    /**ADC1 GPIO Configuration    

    PA1     ------> ADC1_IN1

    PA2     ------> ADC1_IN2

    */

    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2;

    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Peripheral DMA init*/

 

    hdma_adc1.Instance = DMA2_Stream0;

    hdma_adc1.Init.Channel = DMA_CHANNEL_0;

    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;

    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;

    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;

    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

    hdma_adc1.Init.Mode = DMA_CIRCULAR;

    hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;

    hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_ENABLE;

    hdma_adc1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)

    {

      Error_Handler();

    }

    __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);

  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */

  }

}

#adc #dma #strange-points
2 REPLIES 2
S.Ma
Principal
Posted on April 22, 2017 at 17:39

From the graph, can you tell how much time is compressed to make such discontinuity?

Could it be that the buffer is sent out by serial interface to PC, or due to DMA_CIRCULAR it is the snapshot where the newest sample meet the oldest one? (check the DMA counter value to know where is the last written sample)

Posted on April 22, 2017 at 20:32

   I don't think that's the serial buffer because I set to see the variable in Coocox and press Run each time I want to see the new values in Debug mode, after that I copy and paste to importation. As you said, it seems to be a DMA Circular problem, because when I disable the DMA continuous request ( hadc1.Init.DMAContinuousRequests = DISABLE;) I got the correct signal wave, and I?m not getting it in the same position because I?m not sampling exactly one period.

0690X00000606r5QAA.png

However, I can?t update the buffer anymore.

That?s what I got when I changed the Length to 512 (hadc1.Init.DMAContinuousRequests = ENABLE;),

0690X00000606rAQAQ.png

After Run again:

0690X00000606rKQAQ.png

And with hadc1.Init.DMAContinuousRequests = DISABLE:

0690X00000606pGQAQ.png

How can I check the DMA counter ? It?s always in 256 for Length = 256 and 512 forLength = 512;