cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with ADCs in dual regular mode

Were-Rabbit
Associate II
Posted on September 23, 2013 at 08:42

I�ve have a problem with the ADCs in dual regular simultaneous mode.

I want to measure 3 channels with ADC1 and 3 channels with ADC2. The conversions are started by software. I want to get 32 acquisitions in DMA mode and then stop the ADCs. The conversions will be started by software again.

My code works fine but after several acquisitions I get sometimes wrong results for ADC2.

  // init DMA and ADC

  DMA_DeInit(DMA1_Channel1);                                        // ADC and DMA handling

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = (32*3);

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel1, &DMA_InitStructure);

  DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);  

  DMA_Cmd(DMA1_Channel1, ENABLE);

 

  // ADC1 configuration

  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 3;

  ADC_Init(ADC1, &ADC_InitStructure);

 

  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_41Cycles5);  

  ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 2, ADC_SampleTime_41Cycles5);  

  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 3, ADC_SampleTime_41Cycles5);  

 

  ADC_DMACmd(ADC1, ENABLE);

  // ADC2 configuration

  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 3;

  ADC_Init(ADC2, &ADC_InitStructure);

 

  ADC_RegularChannelConfig(ADC2, ADC_Channel_7, 1, ADC_SampleTime_41Cycles5);   

  ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 2, ADC_SampleTime_41Cycles5);   

  ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 3, ADC_SampleTime_41Cycles5);  

  ADC_ExternalTrigConvCmd(ADC2, ENABLE);

  // calibrate ADC1

  ADC_Cmd(ADC1, ENABLE);

  ADC_ResetCalibration(ADC1);

  while(ADC_GetResetCalibrationStatus(ADC1));

  ADC_StartCalibration(ADC1);

  while(ADC_GetCalibrationStatus(ADC1));

  // calibrate ADC2

  ADC_Cmd(ADC2, ENABLE);

  ADC_ResetCalibration(ADC2);

  while(ADC_GetResetCalibrationStatus(ADC2));

  ADC_StartCalibration(ADC2);

  while(ADC_GetCalibrationStatus(ADC2));

 

   __disable_interrupt();

 

   // DMA1 interrupt

  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

 

  __enable_interrupt();

}

void ADC_Start(void)

{

  DMA_Cmd(DMA1_Channel1, ENABLE);

  ADC_Cmd(ADC1, ENABLE);  

  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

// DMA Mode

void DMA_ADC1_2_IRQHandler(void)

{

  DMA_Cmd(DMA1_Channel1, DISABLE);                  // ADC and DMA handling

  DMA_ClearFlag(DMA1_FLAG_TC1);

 

  ADC_Cmd(ADC1, DISABLE);

}

#provide-complete-code #adc-dma-dualmode
4 REPLIES 4
Posted on September 23, 2013 at 13:33

You want it done once, then don't use circular mode DMA.

Don't enable DMA until after you calibrate.

Wrong results how? Out of sequence, what specifically?

Want me to look at this? Provide a functionally complete/stand-alone, compilable code example, and specify what chip is being used.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Were-Rabbit
Associate II
Posted on September 23, 2013 at 15:49

Hi Clive1,

tahnk you for your support. It was a problem with an interrupt.

Posted on September 23, 2013 at 16:00

It was a problem with an interrupt.

DMA1_Channel1_IRQHandler()?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Were-Rabbit
Associate II
Posted on September 23, 2013 at 16:27

No, the problem was the UART interrupt.