AnsweredAssumed Answered

stm32f4 adc dma timer

Question asked by ramani.nisarg on Jun 22, 2015
Latest reply on Jun 22, 2015 by Clive One
I need advice on this

Sample adc every 2us, using ADC3 + DMA + TIM3 for STM32F407.

as per requirement of project, i need to read 2 adc channel simultenously ( on GPIO PC1 & PC2) at every 2us.
collect 10 converted value (i.e. 20us time). then disable sampling for 100us. During OFF time of sampling calculate average of 10 values.
after 100us start sampling again and so on...

for this, i have used ADC3 + DMA + TIM3 for STM32F407.
Below is code i have tried, but failed.

As per my understanding, after ENABLE of timer, it will give interrupt to ADC, ADC will sample and sampled data transfered to DMA, and will stored in ADC3ConvertedValue[] array.


/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"

#define BUFFERLENGHT_ADC3         10        //array of 10

/* Private variables ---------------------------------------------------------*/
uint16_t ADC3ConvertedValue[BUFFERLENGHT_ADC3];


void ADCInit()
{
  uint16_t PrescalerValue = 0;
 
  GPIO_InitTypeDef              GPIO_InitStructure;
  NVIC_InitTypeDef              NVIC_InitStructure;
  TIM_TimeBaseInitTypeDef       TIM_TimeBaseStructure;
  DMA_InitTypeDef               DMA_InitStructure;
  ADC_InitTypeDef               ADC_InitStructure;
  ADC_CommonInitTypeDef         ADC_CommonInitStructure;

 
  /************RCC*************/
  /* Enable DMA & GPIO clock */
  RCC_AHB1PeriphClockCmdRCC_AHB1Periph_DMA2| RCC_AHB1Periph_GPIOCENABLE);
  /* Enable ADCx clock */
  RCC_APB2PeriphClockCmdRCC_APB2Periph_ADC3ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 
  /************GPIO*************/
  /* Configure GPIO Pin as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1| GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
 
 
  /************NVIC************/
  /* Configure the NVIC Preemption Priority Bits */
//  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  /* NVIC Configuration */  
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 

  /************TIMER************/
  /* Compute the prescaler value */
  PrescalerValue = (uint16_t) ((SystemCoreClock/2) / 1000000) - 1;
  /* Time base configuration */
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Period = 2;        //for 2us
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
 
  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
  TIM_Cmd(TIM2, ENABLE);
 

  /************DMA************/
  /* DMA STREAM configuration */
  DMA_InitStructure.DMA_Channel = DMA_Channel_2;                                //DMA CHannel
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS;         //DMA address
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC3ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;          
  DMA_InitStructure.DMA_BufferSize = BUFFERLENGHT_ADC3;                  
  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_Circular;                               
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;                           
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;             
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;                   
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;           
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
 
    /* Enable DMA Stream Half / Transfer Complete interrupt */
  DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);

  /* Enable DMAx channely */
  DMA_Cmd(DMA2_Stream0, ENABLE);
 
 
  /************ADC************/
  /* ADC Common Init */
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                      //only ADC3 is used - independent
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);
 
  /* ADC3 Init */
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;                        //12 bit
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 2;
  ADC_Init(ADC3, &ADC_InitStructure);

  /* ADC3 regular channel12 configuration */
  ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_480Cycles);
  ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 2, ADC_SampleTime_480Cycles);

 /* Enable DMA request after last transfer (Single-ADC mode) */
//  ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
 
  ADC_DMACmd(ADC3, ENABLE);
  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);
}






Outcomes