AnsweredAssumed Answered

STM32L_Discovery Multichannel ADC example

Question asked by abimbola.idris on Nov 9, 2015
Latest reply on Nov 16, 2015 by abimbola.idris
I have been trying extend Clive1 ADC_DMA example on STM32L_Discovery to do multi-channel conversion. But am struggling to get the NVIC_IRQ Handle for the two channel right. Can someone assist me with an example of multichannel ADC on STM32L?  The modified code is given below.


include <stm32l1xx.h>



ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
__IO uint16_t ADC_ConvertedValue[2];

   void LEDInit(void)
{
      /*Enable GPIOB & GPIOC clock and Configure PB6 and PB7 in output mode*/
     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE);</div>
       
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
          
  /* Configure PC4&PC5 (ADC Channel14 & 15) in analog mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

}

void NVIC_Config(void){
     NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the DMA Stream IRQ Channel */
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;</div>
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;</div>
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;</div>
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;</div>
  NVIC_Init(&NVIC_InitStructure);</div>
}

void ADC_DMA_Config(void)
{
     
     /* Enable the HSI oscillator */
     RCC_HSICmd(ENABLE);
        /* Check that HSI oscillator is ready */
  while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);</div>
  
     
     /* Enable ADC1 clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);</div>
      
  /* Deinitialize ADC */
     ADC_DeInit(ADC1);
     ADC_CommonStructInit(&ADC_CommonInitStructure);</div>
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;</div>
  ADC_CommonInit(&ADC_CommonInitStructure);</div>
     
  /* ADC1 configuration */
     ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;</div>
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;</div>
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;</div>
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;</div>
     ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;</div>
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;</div>
  ADC_InitStructure.ADC_NbrOfConversion = 2;</div>
  ADC_Init(ADC1, &ADC_InitStructure);
 /* ADC1 regular channel18 configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_192Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 2, ADC_SampleTime_192Cycles);

/* Enable ADC1 Power Down during Delay */
  ADC_PowerDownCmd(ADC1, ADC_PowerDown_Idle_Delay, ENABLE);
 
  /*------------------------ DMA1 configuration ------------------------------*/</div>
  /* Enable DMA1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);</div>
  /* DMA1 channel1 configuration */
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) &ADC1->DR;</div>
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue[0];</div>
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 2;</div>
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;</div>
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;</div>
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;</div>
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;</div>
  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);
  
     /* Enable DMA Stream Half / Transfer Complete interrupt */
  DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE);
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);
     
  /* Enable the request after last transfer for DMA Circular mode */
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);</div>

  /*----------------- ADC1 configuration with DMA enabled --------------------*/
  
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

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

  /* Wait until the ADC1 is ready */
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET);
  
  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConv(ADC1);
}

int main (void){
   double x = 0, y = 0;
     LEDInit();
     NVIC_Config();
     GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_RESET);
  GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET);
     ADC_DMA_Config();
     while (1)
     {
          x = ADC_ConvertedValue[0] * 3.3/4095; //get analog value and convert to volts, 12bit ADC

        if(y > 2)
        {
          GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_SET);//Red LED on
        }
        else 
        {
          GPIO_WriteBit(GPIOB, GPIO_Pin_7, Bit_RESET);//Red LED off 
        }

        y = ADC_ConvertedValue[1] * 3.3/4095; //get analog value and convert to volts, 12bit ADC

        if(x > 2)
        {
          GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET);// Green LED on
        }
        else 
        {
          GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_RESET);//Green LED off 
        }

     }
}

Outcomes