2013-09-22 11:42 PM
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-dualmode2013-09-23 04:33 AM
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.2013-09-23 06:49 AM
Hi Clive1,
tahnk you for your support. It was a problem with an interrupt.2013-09-23 07:00 AM
It was a problem with an interrupt.
DMA1_Channel1_IRQHandler()?2013-09-23 07:27 AM
No, the problem was the UART interrupt.