2016-04-25 08:17 PM
Hi.
I’m trying to get the DMA to transfer 10 data bytes from the ADC to memory (STM32F3.
So far I can get this to work in ADCDMA circular mode, and this 10 sample conversion takes place continuously.
I actually want the ADC to do 10 conversions only, and the DMA to transfer these into a buffer, and then at some time latter in code, I want to be able to start this 10 sample conversion again.
I made some changes which at the moment have not worked. With my current configuration I can sample 10 times and fill the buffer, but I cannot restart the ADC+DMA to do it again.
Can anyone point me in the right direction. I have included what is my code.
Thankskvresto
DMA INT:
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,
ENABLE
);
DMA_InitTypeDef
DMA_InitStructure;
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.
DMA_PeripheralBaseAddr
= ADC_CDR_ADDRESS;
DMA_InitStructure.
DMA_MemoryBaseAddr
= (
uint32_t
)&ADCConvertedBuffer;
DMA_InitStructure.
DMA_DIR
= DMA_DIR_PeripheralSRC;
DMA_InitStructure.
DMA_BufferSize
= 10;
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_HalfWord;
DMA_InitStructure.
DMA_Mode
= DMA_Mode_Normal; <
---------
DMA_Mode_Circular;
DMA_InitStructure.
DMA_Priority
= DMA_Priority_Medium;
DMA_InitStructure.
DMA_M2M
= DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1,
ENABLE
); ADC INIT below: ----------------------------------------------------------------------------------------------------------ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
ADC_StructInit(&ADC_InitStructure); //Fills ADC_InitStruct with its default value.
ADC_VoltageRegulatorCmd(ADC1, ENABLE);
Delay(0x2FFFF);
ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1) != RESET );
calibration_value_1 = ADC_GetCalibrationValue(ADC1);ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot; ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
/* */
ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Enable; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0; ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable; ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable; ADC_InitStructure.ADC_NbrOfRegChannel = 1; ADC_Init(ADC1, &ADC_InitStructure);ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_7Cycles5);
ADC_DMAConfig(ADC1, ADC_DMAMode_OneShot); <------------------ ADC_DMAMode_Circular);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
ADC_StartConversion(ADC1);
2016-04-26 03:20 AM
Hi k.kvresto,
You need to use a timer to trig the ADC and launch conversion and DMA transfer. ADC Dual/triple interleaved mode is suitable for you with Multimode DMA request . I recommend the ''ADC_DualModeInterleaved'' example inhttp://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/LN1939/PF257901
(since you are using the standard peripheral library) at this path: STM32F4xx_DSP_StdPeriph_Lib_V1.6.1\Project\STM32F4xx_StdPeriph_Examples\ADC\ADC_DualModeInterleaved -Hannibal-2016-04-26 04:56 AM
ok ,thank you Hannibal.