2017-04-22 07:17 AM
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:
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-points2017-04-22 08:39 AM
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)
2017-04-22 01:32 PM
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.
However, I can?t update the buffer anymore.
That?s what I got when I changed the Length to 512 (hadc1.Init.DMAContinuousRequests = ENABLE;),
After Run again:
And with hadc1.Init.DMAContinuousRequests = DISABLE:
How can I check the DMA counter ? It?s always in 256 for Length = 256 and 512 forLength = 512;