cancel
Showing results for 
Search instead for 
Did you mean: 

ADC in conjustion with DMA

Pejwaak
Associate II

Hi

I am facing an odd problem with ADC in conjunction with DMA on STM32L151V8T-A. 

I can see that it measures all three channels. However, the result of each channel is stored in the first element of my results array (Result[3]). 

Every time that the callback function is called the results of one out of three channels is stored in Result[0] element. It is as if the memory address is not increasing.

Can somebody help?

1 ACCEPTED SOLUTION

Accepted Solutions

I attached a project where I did 3 channels conversion in continuous mode with DMA on STM32L152D_EVAL board. Unfortunately, I don't have your board on hands.

The three converted channels are:

- Channel 31: potentiometer

- Channel 16: temperature sensor

- Channel 17: Vrefint

I tested the project with IAR, you can port it easily to CubeIDE with CubeMx.

As you can see in this screenshot, the data converted are arranged in the correct order.

SofLit_0-1711122362478.png

You can inspire from my project to find your issue.

Please select this answer if it does answer your question.

 

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.

View solution in original post

16 REPLIES 16
GwenoleB
ST Employee

Hello @Pejwaak,

Please, make sure in your DMA settings you have correctly enable the incrementing address of "Destination Address".

Feel free to share your settings :)

Kind Regards,

Gwénolé

Pejwaak
Associate II

Hi

Thanks for getting to me. I am not writing the low level code. I am using HAL library and I assumed as long as I follow the working examples. It should do the same thing although this is a different STM32 microcontroller.

Here is the part of the code that runs it. I also use the call back function to sent the ADCFlag.

HAL_ADC_Start_DMA(&hadc, ADCArray, 3);
  HAL_TIM_Base_Start_IT(&htim2);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
  if(ADCFlag){
  ADCStat = HAL_ADC_GetState(&hadc);
  if(ADCStat == 0){
    ADCFlag = 0;
    HAL_ADC_Start_DMA(&hadc, ADCArray, 3);
  }
 

Hello,

Did you enable Scan mode?

SofLit_0-1710862082364.png

Did you enable Memory incrementation in DMA config as stated by @GwenoleB ?

SofLit_1-1710862158687.png

 

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.

Hi

Yes, I have taken every standard step according to the examples. Like I said all channels are being sampled but at the end of the sequence only one channel is written to ACDArray[0] and the rest remain zero. then at then end of next sequence the values for another channel is written two ACDArray[0] and the rest remain zero. It is really odd. 

You need to share your project for an efficient help.

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.
Pejwaak
Associate II

Hi

Thanks it is a lo of line. I am going to put the relevant bits here. Hopefully it will work.

static void MX_ADC_Init(void)
{

/* USER CODE BEGIN ADC_Init 0 */

/* USER CODE END ADC_Init 0 */

ADC_ChannelConfTypeDef sConfig = {0};

/* USER CODE BEGIN ADC_Init 1 */

/* USER CODE END ADC_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_10B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;
hadc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;
hadc.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.NbrOfConversion = 3;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = ENABLE;
if (HAL_ADC_Init(&hadc) != 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_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_16CYCLES;
if (HAL_ADC_ConfigChannel(&hadc, &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 = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc, &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_6;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC_Init 2 */

/* USER CODE END ADC_Init 2 */

}

This is the configuration of ADC. The rest of the code is presented above. It is very simple. Start with DMA, set the flag by callback function, reset the flag and restart the ADC with DMA again. 

Could you please share your .ioc file?

PS: next time please use </> button to insert your code for source code readability.

 

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.
#MicroXplorer Configuration settings - do not modify
ADC.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_0
ADC.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_2
ADC.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_6
ADC.ClockPrescaler=ADC_CLOCK_ASYNC_DIV4
ADC.ContinuousConvMode=ENABLE
ADC.DMAContinuousRequests=ENABLE
ADC.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,ClockPrescaler,ScanConvMode,ContinuousConvMode,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,NbrOfConversion,DMAContinuousRequests,Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,Resolution
ADC.NbrOfConversion=3
ADC.NbrOfConversionFlag=1
ADC.Rank-0\#ChannelRegularConversion=1
ADC.Rank-1\#ChannelRegularConversion=2
ADC.Rank-3\#ChannelRegularConversion=3
ADC.Resolution=ADC_RESOLUTION_10B
ADC.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_16CYCLES
ADC.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_16CYCLES
ADC.SamplingTime-3\#ChannelRegularConversion=ADC_SAMPLETIME_16CYCLES
ADC.ScanConvMode=ADC_SCAN_ENABLE
Dma.ADC.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC.0.Instance=DMA1_Channel1
Dma.ADC.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.ADC.0.MemInc=DMA_MINC_ENABLE
Dma.ADC.0.Mode=DMA_CIRCULAR
Dma.ADC.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.ADC.0.PeriphInc=DMA_PINC_DISABLE
Dma.ADC.0.Priority=DMA_PRIORITY_LOW
Dma.ADC.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
Dma.Request0=ADC
Dma.RequestsNb=1
File.Version=6
KeepUserPlacement=false
Mcu.Family=STM32L1
Mcu.IP0=ADC
Mcu.IP1=DAC
Mcu.IP2=DMA
Mcu.IP3=NVIC
Mcu.IP4=RCC
Mcu.IP5=SYS
Mcu.IP6=TIM2
Mcu.IP7=USART3
Mcu.IPNb=8
Mcu.Name=STM32L151V(8-B)TxA
Mcu.Package=LQFP100
Mcu.Pin0=PH0-OSC_IN
Mcu.Pin1=PH1-OSC_OUT
Mcu.Pin10=PD13
Mcu.Pin11=PD14
Mcu.Pin12=PA13
Mcu.Pin13=PA14
Mcu.Pin14=VP_SYS_VS_Systick
Mcu.Pin15=VP_TIM2_VS_ClockSourceINT
Mcu.Pin2=PA0-WKUP1
Mcu.Pin3=PA2
Mcu.Pin4=PA4
Mcu.Pin5=PA6
Mcu.Pin6=PE11
Mcu.Pin7=PE12
Mcu.Pin8=PD8
Mcu.Pin9=PD9
Mcu.PinsNb=16
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32L151V8TxA
MxCube.Version=6.4.0
MxDb.Version=DB.6.0.40
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.DMA1_Channel1_IRQn=true\:0\:0\:false\:false\:true\:false\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVC_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true
NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
PA0-WKUP1.GPIOParameters=GPIO_Label
PA0-WKUP1.GPIO_Label=Water_Tempe1
PA0-WKUP1.Locked=true
PA0-WKUP1.Mode=IN0
PA0-WKUP1.Signal=ADC_IN0
PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PA2.GPIOParameters=GPIO_Label
PA2.GPIO_Label=XDCR_TEMP1
PA2.Mode=IN2
PA2.Signal=ADC_IN2
PA4.GPIOParameters=GPIO_Label
PA4.GPIO_Label=Amp_PSU_Voltage_Adjust
PA4.Signal=COMP_DAC1_group
PA6.Mode=IN6
PA6.Signal=ADC_IN6
PD13.GPIOParameters=GPIO_Label
PD13.GPIO_Label=V24_Voltage_PGOOD
PD13.Locked=true
PD13.Signal=GPIO_Input
PD14.GPIOParameters=GPIO_Label
PD14.GPIO_Label=Amp_Voltage_PGOOD
PD14.Locked=true
PD14.Signal=GPIO_Input
PD8.Locked=true
PD8.Mode=Asynchronous
PD8.Signal=USART3_TX
PD9.Locked=true
PD9.Mode=Asynchronous
PD9.Signal=USART3_RX
PE11.GPIOParameters=GPIO_Label
PE11.GPIO_Label=Test_Output1
PE11.Locked=true
PE11.Signal=GPIO_Output
PE12.GPIOParameters=GPIO_Label
PE12.GPIO_Label=Test_Output2
PE12.Locked=true
PE12.Signal=GPIO_Output
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=false
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32L151V8TxA
ProjectManager.FirmwarePackage=STM32Cube FW_L1 V1.10.4
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=Control_Centre_Eval.ioc
ProjectManager.ProjectName=Control_Centre_Eval
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=STM32CubeIDE
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC_Init-ADC-false-HAL-true,4-MX_DAC_Init-DAC-false-HAL-true,5-MX_DMA_Init-DMA-false-HAL-true,6-MX_USART3_UART_Init-USART3-false-HAL-true,7-MX_TIM2_Init-TIM2-false-HAL-true
RCC.48MHZClocksFreq_Value=32000000
RCC.AHBFreq_Value=32000000
RCC.APB1Freq_Value=32000000
RCC.APB1TimFreq_Value=32000000
RCC.APB2CLKDivider=RCC_HCLK_DIV16
RCC.APB2Freq_Value=2000000
RCC.APB2TimFreq_Value=4000000
RCC.FCLKCortexFreq_Value=32000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=32000000
RCC.HSE_VALUE=8000000
RCC.HSI_VALUE=16000000
RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,LSE_VALUE,LSI_VALUE,MCOPinFreq_Value,MSI_VALUE,PLLCLKFreq_Value,PLLMUL,PLLSourceVirtual,PWRFreq_Value,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,TIMFreq_Value,TimerFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value
RCC.LSE_VALUE=32768
RCC.LSI_VALUE=37000
RCC.MCOPinFreq_Value=32000000
RCC.MSI_VALUE=2097000
RCC.PLLCLKFreq_Value=32000000
RCC.PLLMUL=RCC_PLL_MUL8
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.PWRFreq_Value=32000000
RCC.RTCFreq_Value=37000
RCC.RTCHSEDivFreq_Value=4000000
RCC.SYSCLKFreq_VALUE=32000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.TIMFreq_Value=32000000
RCC.TimerFreq_Value=32000000
RCC.VCOInputFreq_Value=8000000
RCC.VCOOutputFreq_Value=64000000
SH.COMP_DAC1_group.0=DAC_OUT1,DAC_OUT1
SH.COMP_DAC1_group.ConfNb=1
TIM2.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
TIM2.IPParameters=Prescaler,Period,AutoReloadPreload
TIM2.Period=999
TIM2.Prescaler=31
USART3.BaudRate=38400
USART3.IPParameters=VirtualMode,BaudRate
USART3.VirtualMode=VM_ASYNC
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM2_VS_ClockSourceINT.Mode=Internal
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
board=custom
isbadioc=false

Here it is. Thanks for continues help :)

Please attach it.

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.