AnsweredAssumed Answered

Problem with ADC DMA and timer

Question asked by montoliu.miquel on Oct 1, 2013
Latest reply on Oct 1, 2013 by Clive One
Hello everyone!
I'm trying to make a program that every x milliseconds is interrupted by a timer, and the timer starts AD conversion. When they have the data, the DMA interrupts and records those values in an array. After that, these values are recorded in package on an SD card.
The problem is that only timer interruption works, and the rest of the process is not running (ADC and DMA).My code is:

main
/*Private variables*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef       TIM_OCInitStructure;
TIM_BDTRInitTypeDef     TIM_BDTRInitStructure;
__IO uint16_t aADCTripleConvertedValue[3];


char vectordelatrama [2048];
int posiciodelvector=0;
char estructura[32];
int a;
int recompte=0;
int enviar=0;


__IO uint32_t TimeOut = 0x0; 


FATFS Fatfs;          /* File system object */
FIL Fil, Fil2;               /* File object */
BYTE Buff[128];          /* File read buffer */




void die (          /* Stop with dying message */
     FRESULT rc     /* FatFs return value */
)
{
}


static void TIM_Config(void)
{
     NVIC_InitTypeDef NVIC_InitStructure;
       /* Enable the TIM1 Trigger and commutation interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);   
}






void INTTIM_Config(void)
{
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* Time base configuration for 5 ms */
TIM_TimeBaseStructure.TIM_Period = 10500 - 1; // 1 MHz down to 10 KHz (0.1 ms)
TIM_TimeBaseStructure.TIM_Prescaler = 16000 - 1; //posar 40!!!
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* TIM2 enable counter */
     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); 
     TIM_Cmd(TIM2, ENABLE);


}




static void ADC_Config(void)
{
  GPIO_InitTypeDef       GPIO_InitStructure;
  DMA_InitTypeDef        DMA_InitStructure;
  ADC_InitTypeDef        ADC_InitStructure;
  ADC_CommonInitTypeDef  ADC_CommonInitStructure;  
  
  /* Enable peripheral clocks *************************************************/
  RCC_AHB1PeriphClockCmd( ADC1_2_CHANNEL_GPIO_CLK , ENABLE);
  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA2 , ENABLE);
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1 , ENABLE);
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC2 , ENABLE);
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC3 , ENABLE);  


  /* Configure ADC Channel 12 pin as analog input *****************************/ 
  GPIO_InitStructure.GPIO_Pin = GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIO_PORT, &GPIO_InitStructure);


  /* DMA2 Stream0 channel0 configuration **************************************/
  DMA_InitStructure.DMA_Channel = DMA_CHANNELx;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&aADCTripleConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 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_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(DMA_STREAMx, &DMA_InitStructure);


  /* DMA2_Stream0 enable and enable interrupts */
  DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
     DMA_Cmd(DMA_STREAMx, ENABLE);


  /* ADC Common configuration *************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_Interl;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;  
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; 
  ADC_CommonInit(&ADC_CommonInitStructure);


  /* ADC1 regular channel 16 configuration ************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 2; //2 o 3??
  ADC_Init(ADC1, &ADC_InitStructure);


  ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_3Cycles);
     ADC_RegularChannelConfig(ADC1, ADC_Channel_18, 1, ADC_SampleTime_3Cycles);
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);


  /* ADC2 regular channel 12 configuration ************************************/
  ADC_Init(ADC2, &ADC_InitStructure);
  /* ADC2 regular channel12 configuration */ 
  //ADC_RegularChannelConfig(ADC2, ADC_CHANNEL, 1, ADC_SampleTime_3Cycles);


  /* ADC3 regular channel 7 configuration ************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC3, &ADC_InitStructure); 
  /* ADC3 regular channel 7 configuration */
  ADC_RegularChannelConfig(ADC3, ADC_Channel_7, 1, ADC_SampleTime_3Cycles);


  /* Enable DMA request after last transfer (multi-ADC mode) ******************/
  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);


  /* Enable ADC1 **************************************************************/
  ADC_Cmd(ADC1, ENABLE);


  /* Enable ADC2 **************************************************************/
  ADC_Cmd(ADC2, ENABLE);


  /* Enable ADC3 **************************************************************/
  ADC_Cmd(ADC3, ENABLE);
     
      ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); // afegit


}  


/*-----------------------------------------------------------------------*/
/* Program Main                                                          */
/*-----------------------------------------------------------------------*/


int main (void) 
{
     FRESULT rc;                    /* Result code */
     DIR dir;                    /* Directory object */
     FILINFO fno;               /* File information object */
     UINT bw, br, i;


     STM_EVAL_LEDInit(LED1);
     STM_EVAL_LEDInit(LED2);
          STM_EVAL_LEDInit(LED3);
     STM_EVAL_LEDInit(LED4);
     
     f_mount(0, &Fatfs);          /* Register volume work area (never fails) */
     
     for(a=0; a < 32; a++)
     {
          if (a<4) estructura[a]= 0x11*(a+1);
          else estructura[a]= 0x00;
     }
     TIM_Config();
     INTTIM_Config();
     ADC_Config();




     while(1){
          if(enviar==1){
               enviar=0;
               STM_EVAL_LEDToggle(LED3);
               for (;;) {
                    rc = f_write(&Fil2, &vectordelatrama+((recompte%2)*1024), 1024, &bw);
               }
               if (rc) die(rc);
               if (recompte==25){
                    rc = f_close(&Fil2);
                    if (rc) die(rc);
                    STM_EVAL_LEDToggle(LED4);
               }
          }
     }
}

interrupts
void TIM2_IRQHandler(void)
{
     //ADC_TempSensorVrefintCmd(ENABLE);
     //ADC_RegularChannelConfig(ADC1,ADC_Channel_16,16,ADC_SampleTime_3Cycles);
     //valor=ADC_GetConversionValue(ADC1);
     ADC_SoftwareStartConv(ADC1);
     STM_EVAL_LEDToggle(LED1);
     TIM_ClearFlag(TIM2, TIM_FLAG_Update);
     TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);




}




/* Configuració de la interrupció associada a la DMA */


void DMA2_Stream0_IRQHandler (void)
{


     DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
     if (recompte < 2) {
          for(i=0; i < tamanyvector;i++) {
               vectordelatrama[i+posiciodelvector]= estructura[i];
          }
     }
     vectordelatrama[posiciodelvector+4]=(aADCTripleConvertedValue[0])>>8;
     vectordelatrama[posiciodelvector+5]=aADCTripleConvertedValue[0];
     vectordelatrama[posiciodelvector+6]=(aADCTripleConvertedValue[1])>>8;
     vectordelatrama[posiciodelvector+7]=aADCTripleConvertedValue[1];
     vectordelatrama[posiciodelvector+8]=(aADCTripleConvertedValue[2])>>8;
     vectordelatrama[posiciodelvector+9]=aADCTripleConvertedValue[2];
     STM_EVAL_LEDToggle(LED2);
     if (posiciodelvector==992){
          posiciodelvector+=32;
          enviar=1;
     }
     if (posiciodelvector==2016){
          enviar=1;
          posiciodelvector=0;
          recompte+=1;
     }
     if (recompte ==25){
          enviar=1;
          ADC_Cmd(ADC1, DISABLE);
          ADC_Cmd(ADC2, DISABLE);
          ADC_Cmd(ADC2, DISABLE);
          DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, DISABLE);
          DMA_Cmd(DMA_STREAMx, DISABLE);
          TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE); 
          TIM_Cmd(TIM2, DISABLE);
     }
     else posiciodelvector+=32;
     
     }
     

Thanks in advance!!

Outcomes