AnsweredAssumed Answered

STM32F103 issues with ADC1 6 channel DMA transfer

Question asked by Laurikainen.Jaakko on Aug 6, 2016
Latest reply on Aug 7, 2016 by Laurikainen.Jaakko
Hello,

I have used ADC1 in 4 channel mode successfully in my project with DMA1 transferring the values in circular mode. Now I needed to add 2 more channels, but for some reason as a result reason the channel values are jumping all over the place now.

I'm using pins PA4-PA7 (ADC1 channels 4-7) + PB0-PB1 (channels 8-9). The channels 8-9 are the ones I now added. Below is the initialization code that I'm using. Let me know if I need to open the preprocessor macros more to make it more understandable.

It doesn't matter what conversion ranks or conversion speeds I use, the result is almost the same. Normally the channel input are at VDD/2 and this seems to result in correct conversion on all the channels. If I pull any pin to VDD or VSS, that channel starts jumping between the desired value and VDD/2. In addition the other channels start to do the same jumping. If I reduce the number of conversion back to 4, the first 4 channels are working correctly.

Any help is appreciated.

001.#define SWITCH_ADC_INSTANCE                 ADC1
002.#define SWITCH_ADC_CLK_ENABLE()             __HAL_RCC_ADC1_CLK_ENABLE()
003.#define SWITCH_ADC_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE()
004.#define SWITCH_ADC_DMA_CHANNEL_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
005.#define SWITCH_ADC_FIRST_CHANNEL_NUMBER     4
006.#define SWITCH_ADC_CHANNEL_1                ADC_CHANNEL_4
007.#define SWITCH_ADC_CHANNEL_2                ADC_CHANNEL_5
008.#define SWITCH_ADC_CHANNEL_3                ADC_CHANNEL_6
009.#define SWITCH_ADC_CHANNEL_4                ADC_CHANNEL_7
010.#define SWITCH_ADC_CHANNEL_5                ADC_CHANNEL_8
011.#define SWITCH_ADC_CHANNEL_6                ADC_CHANNEL_9
012.#define SWITCH_ADC_CHANNEL_1_GPIO_PIN       GPIO_PIN_4
013.#define SWITCH_ADC_CHANNEL_2_GPIO_PIN       GPIO_PIN_5
014.#define SWITCH_ADC_CHANNEL_3_GPIO_PIN       GPIO_PIN_6
015.#define SWITCH_ADC_CHANNEL_4_GPIO_PIN       GPIO_PIN_7
016.#define SWITCH_ADC_CHANNEL_5_GPIO_PIN       GPIO_PIN_0
017.#define SWITCH_ADC_CHANNEL_6_GPIO_PIN       GPIO_PIN_1
018.#define SWITCH_ADC_GPIO                     GPIOA
019.#define SWITCH_ADC_GPIO2                    GPIOB
020. #define ADC_SAMPLING_TIME ADC_SAMPLETIME_239CYCLES_5
021.static ADC_ChannelConfTypeDef gADCChannels[SWITCH_NUM_OF_CHANNELS] =
022.{
023.        [SWITCH_CHANNEL_1] =
024.        {
025.                .Channel = SWITCH_ADC_CHANNEL_1,
026.                .Rank = 1,
027.                .SamplingTime = ADC_SAMPLING_TIME
028.        },
029.        [SWITCH_CHANNEL_2] =
030.        {
031.                .Channel = SWITCH_ADC_CHANNEL_2,
032.                .Rank = 2,
033.                .SamplingTime = ADC_SAMPLING_TIME
034.        },
035.        [SWITCH_CHANNEL_3] =
036.        {
037.                .Channel = SWITCH_ADC_CHANNEL_3,
038.                .Rank = 3,
039.                .SamplingTime = ADC_SAMPLING_TIME
040.        },
041.        [SWITCH_CHANNEL_4] =
042.        {
043.                .Channel = SWITCH_ADC_CHANNEL_4,
044.                .Rank = 4,
045.                .SamplingTime = ADC_SAMPLING_TIME
046.        },
047.        [SWITCH_CHANNEL_5] =
048.        {
049.                .Channel = SWITCH_ADC_CHANNEL_5,
050.                .Rank = 5,
051.                .SamplingTime = ADC_SAMPLING_TIME
052.        },
053.        [SWITCH_CHANNEL_6] =
054.        {
055.                .Channel = SWITCH_ADC_CHANNEL_6,
056.                .Rank = 6,
057.                .SamplingTime = ADC_SAMPLING_TIME
058.        }
059.};
060. 
061.// DMA stores ADC conversions here
062.static u16 gChannelRawValue[10];
063. 
064. 
065./////////////////////////////////// INIT CODE:
066. 
067.    // De-init of ADC is required, otherwise init would fail
068.    ADCHandle.Instance = SWITCH_ADC_INSTANCE;
069.    HALRet = HAL_ADC_DeInit(&ADCHandle);
070.    if (HALRet != HAL_OK)
071.    {
072.        printf("[SWITCH] Failed to de-init ADC (%d, %d, %d).\r\n", HALRet, ADCHandle.ErrorCode, ADCHandle.State);
073.        retVal = SWITCH_ERROR;
074.    }
075. 
076.    ADCHandle.Init.ScanConvMode = ADC_SCAN_ENABLE;
077.    ADCHandle.Init.ContinuousConvMode = ENABLE;
078.    ADCHandle.Init.DiscontinuousConvMode = DISABLE;
079.    ADCHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
080.    ADCHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
081.    ADCHandle.Init.NbrOfConversion = SWITCH_NUM_OF_CHANNELS;
082.    HALRet = HAL_ADC_Init(&ADCHandle);
083.    if (HALRet != HAL_OK)
084.    {
085.        printf("[SWITCH] Failed to init ADC (%d, %d, %d).\r\n", HALRet, ADCHandle.ErrorCode, ADCHandle.State);
086.        retVal = SWITCH_ERROR;
087.    }
088. 
089.    switchChannel_e channel;
090.    for (channel = 0; channel < SWITCH_NUM_OF_CHANNELS; channel++)
091.    {
092.        HALRet = HAL_ADC_ConfigChannel(&ADCHandle, &gADCChannels[channel]);
093.        if (HALRet != HAL_OK)
094.        {
095.            printf("[SWITCH] Failed to init ADC channel %d (%d).\r\n", channel, HALRet);
096.            retVal = SWITCH_ERROR;
097.        }
098.    }
099. 
100.    HALRet = HAL_ADCEx_Calibration_Start(&ADCHandle);
101.    if (HALRet != HAL_OK)
102.    {
103.        printf("[SWITCH] Failed to calibrate ADC (%d).\r\n", HALRet);
104.        retVal = SWITCH_ERROR;
105.    }
106. 
107.    HALRet = HAL_ADC_Start_DMA(&ADCHandle, (uint32_t *)&gChannelRawValue[0], ARRAYLEN(gChannelRawValue));
108.    if (HALRet != HAL_OK)
109.    {
110.        printf("[SWITCH] Failed to start ADC in DMA mode (%d).\r\n", HALRet);
111.        retVal = SWITCH_ERROR;
112.    }
113. 
114.///////////////////////////////// MSP INIT CODE
115.void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
116.{
117.    if(hadc->Instance == SWITCH_ADC_INSTANCE)
118.    {
119.        GPIO_InitTypeDef GPIO_InitStruct;
120.        HAL_StatusTypeDef HALRet;
121. 
122.        SWITCH_ADC_CLK_ENABLE();
123.        SWITCH_ADC_GPIO_CLK_ENABLE();
124.        SWITCH_ADC_DMA_CHANNEL_CLK_ENABLE();
125. 
126.        GPIO_InitStruct.Pin =   SWITCH_ADC_CHANNEL_1_GPIO_PIN |
127.                                SWITCH_ADC_CHANNEL_2_GPIO_PIN |
128.                                SWITCH_ADC_CHANNEL_3_GPIO_PIN |
129.                                SWITCH_ADC_CHANNEL_4_GPIO_PIN;
130.        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
131.        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
132.        HAL_GPIO_Init(SWITCH_ADC_GPIO, &GPIO_InitStruct);
133. 
134.        GPIO_InitStruct.Pin =   SWITCH_ADC_CHANNEL_5_GPIO_PIN |
135.                                SWITCH_ADC_CHANNEL_6_GPIO_PIN;
136.        HAL_GPIO_Init(SWITCH_ADC_GPIO2, &GPIO_InitStruct);
137. 
138.        gDMAHandle.Instance = SWITCH_TIMER_DMA_INSTANCE;
139.        gDMAHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
140.        gDMAHandle.Init.PeriphInc = DMA_PINC_DISABLE;
141.        gDMAHandle.Init.MemInc = DMA_MINC_ENABLE;
142.        gDMAHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
143.        gDMAHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
144.        gDMAHandle.Init.Mode = DMA_CIRCULAR;
145.        gDMAHandle.Init.Priority = DMA_PRIORITY_LOW;
146. 
147.        HALRet = HAL_DMA_Init(&gDMAHandle);
148.        if (HALRet != HAL_OK)
149.        {
150.            printf("[SWITCH] Failed to init DMA (%d).\r\n", HALRet);
151.            gInitStatus = SWITCH_ERROR;
152.        }
153. 
154.        __HAL_LINKDMA(hadc, DMA_Handle, gDMAHandle);
155.    }
156.}


Outcomes