2021-11-10 12:37 AM
So, with ADC1 i enabled and disabled the ADC1 with Capture Compare interrupt, and the found the mean of the data collected in the buffer of DMA, this is all good. But, when i use ADC2 and ADC3, how can I allocate the different Buffersize for each ADC's?? so that i can collect the data stored in each buffer to find the mean value of the data stored in each ADC.
Below code is the initialization of DMA and ADC's (however for single ADC's DMA initialization is working, but if i enable ADC2 and ADC3 which has different channel's how can i initialize different buffersize for each ADC's so that i can take each buffer to process it), what approach is suitable to do that.
Below code is for initializing the ADC's channel and stream.
cADCReadout::sADCInitStruct adc1;
adc1.ADCChannel = ADC1;
adc1.DMAChannel = DMA_Channel_0;
adc1.DMAStream = DMA2_Stream0;
adc1.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
cADCReadout::sADCInitStruct adc2;
adc2.ADCChannel = ADC2;
adc2.DMAChannel = DMA_Channel_1;
adc2.DMAStream = DMA2_Stream3;
adc2.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
cADCReadout::sADCInitStruct adc3;
adc3.ADCChannel = ADC3;
adc3.DMAChannel = DMA_Channel_2;
adc3.DMAStream = DMA2_Stream1;
adc3.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
m_oADC1.initialize(adc1);
m_oADC1.addChannel(GPIOA, GPIO_Pin_1,ADC_Channel_1,ADC_SampleTime_112Cycles);
m_oADC1.initialize(adc2);
m_oADC1.addChannel(GPIOA, GPIO_Pin_2,ADC_Channel_2,ADC_SampleTime_112Cycles);
m_oADC1.initialize(adc3);
m_oADC1.addChannel(GPIOA, GPIO_Pin_3,ADC_Channel_3,ADC_SampleTime_112Cycles);
Below is the function for DMA and ADC initialization.
void cADCReadout::initialize(sADCInitStruct init)
{
m_sInitStruct = init;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
//DMA
DMA_InitStructure.DMA_Channel = init.DMAChannel;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(init.ADCChannel->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&m_aRecBuffer);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = BUFFERSIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(init.DMAStream, &DMA_InitStructure);
DMA_Cmd(init.DMAStream, ENABLE);
//ADC
ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode =ADC_DMAAccessMode_1;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion =3;
ADC_Init(init.ADCChannel, &ADC_InitStructure);
ADC_EOCOnEachRegularChannelCmd(init.ADCChannel, ENABLE);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(init.ADCChannel, DISABLE);
// ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
}
2021-11-10 05:23 AM
If the ADCs are independent, you can choose whatever buffer size you want. Looks like you're running in triple mode, but it appears the hardware can still support different buffer sizes for each ADC. I doubt this is configurable within CubeMX.
uint16_t adc1_buffer[256];
uint16_t adc2_buffer[512];
uint16_t adc3_buffer[1024];
> It would really helpfull if any one could also let me know the ADC clock value for the stm32f4 chip with ADC prescaler 2.
The ADC clock comes from the AHB2 clock, PCLK2. With a /2 prescaler, the clock would be PCLK2/2. You can use CubeMX to see a visualization of this, or consult the reference manual. The reference manual has much more technical information than the datasheet which contains only device-specific information.
2021-11-11 12:07 AM
Yes, i am running in triple mode, i tried the way you suggested before, but the problem is whichever ADC i initialize last only that ADC buffer is getting filled, the first 2 ADC buffer is still empty, that is the problem i am facing.
For example:
cADCReadout::sADCInitStruct adc1;
adc1.ADCChannel = ADC1;
adc1.DMAChannel = DMA_Channel_0;
adc1.DMAStream = DMA2_Stream0;
adc1.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
adc1.buffer = m_aRecBufferADC1;
adc1.buffersize = c_uiBufferSizeADC1;
m_oADC1.addChannel(GPIOA, GPIO_Pin_1,ADC_Channel_1,ADC_SampleTime_112Cycles);
m_oADC1.initialize(adc1);
cADCReadout::sADCInitStruct adc2;
adc2.ADCChannel = ADC2;
adc2.DMAChannel = DMA_Channel_1;
adc2.DMAStream = DMA2_Stream3;
adc2.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
adc2.buffer = m_aRecBufferADC2;
adc2.buffersize = c_uiBufferSizeADC2;
m_oADC1.initialize(adc2);
m_oADC1.addChannel(GPIOA, GPIO_Pin_2,ADC_Channel_2,ADC_SampleTime_112Cycles);
cADCReadout::sADCInitStruct adc3;
adc3.ADCChannel = ADC3;
adc3.DMAChannel = DMA_Channel_2;
adc3.DMAStream = DMA2_Stream1;
adc3.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
adc3.buffer = m_aRecBufferADC3;
adc3.buffersize = c_uiBufferSizeADC3;
m_oADC1.addChannel(GPIOA, GPIO_Pin_3,ADC_Channel_3,ADC_SampleTime_112Cycles);
m_oADC1.initialize(adc3);
In the above code only last initialized ADC's buffer is getting filled, i.e., ADC3 is getting filled and the other ADC's (ADC1, and ADC2) buffer not. If I interchange the order by putting ADC3 in ADC2 place then only ADC2 buffer is getting filled. Inside the 'initialize' function i am configuring ADC and DMA, however each ADC has its own buffer, as you can see in the above code.
2021-11-11 05:57 AM
One option would be to run them in independent mode and use a timer for the trigger.
There may be another solution, but I can't invest the time to find it.
2021-11-11 06:05 AM
Tried running in independent mode, but still its not working, still same problem. from the above code of ADc and DMA configuration is there anything i have to change other than independent mode??
2021-11-11 07:03 AM
2021-11-16 04:53 AM
I solved it thank you for your help. However i have some other confusions, it would be really helpfull if you could kindly help.
2, I read the below statement in some forum, can you please confirm if it is right??
"if you want ADC conversions to be started each time on specific trigger event you should not use continuous mode. In other words, change:''
hadc1.Init.ContinuousConvMode = ENABLE;
to
hadc1.Init.ContinuousConvMode = DISABLE;
is this statement true?
if yes, then will i still be able to use the triggering of ADC during the rising edge of the pulse in continuous mode? Does yes mean i cannot use the below statement "rising edge triggering" with contniuous mode enabled for triggering the ADC?
Because when i use it with conintuous mode it is all working fine with me, i mean in continuous mode enabled and with rising edge triggering i am able to trigger and get the ADC value and my buffer is also full since it is in continuous mode. So, i am bit afraid if it is a right method to do.
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising ;