AnsweredAssumed Answered

STM32F4 ADC 2channels + DMA

Question asked by Tomas on Dec 30, 2013
Latest reply on Nov 13, 2015 by Clive One
I have realized 2channels ADC (PC1, PC2) with DMA. I found and used many examples in forum and ST examples, but It still do not work. It is depressing:-)

My problem is: 
1) If I change the voltage on PC1, first channel works, but second channel shows the value too (it is smaller than first one)
2) If I change the voltage on PC2, it does not appear in either channel.

Thank you for help


/* Includes ------------------------------------------------------------------*/
#include "main.h"
 
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define MSG1        "This is my console  "
#define MSG2        " U    = %d,%d V     "
#define MSG3        " Raw  = %d          "
#define MSG4        " T    = %d,%d oC    "
#define LINENUM     0x15
#define FONTSIZE    Font12x12
 
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADCConvertedValue[2];
__IO uint32_t ADCConvertedVoltage[2];
 
/* Private function prototypes -----------------------------------------------*/
static void Display_Init(void);
static void Display(void);
void pinout_config(void);
 
/* Private functions ---------------------------------------------------------*/
 
int main(void)
{
  pinout_config();
  Display_Init();
 
  if (SysTick_Config(SystemCoreClock / 1000))
  {
    /* Capture error */
    while (1);
  }
 
  while (1)
  {
    // display on screen
    Display();
 
    // delay
    Delay(200);
  }
}
 
 
/**
  * @brief  Display Init (LCD)
  * @param  None
  * @retval None
  */
static void Display_Init(void){
  /* Initialize the LCD */
  LCD_Init();
  LCD_LayerInit();
 
  /* Eable the LTDC */
  LTDC_Cmd(ENABLE);
 
  /* Set LCD Background Layer  */
  LCD_SetLayer(LCD_BACKGROUND_LAYER);
 
  /* Clear the Background Layer */
  LCD_Clear(LCD_COLOR_WHITE);
 
  /* Configure the transparency for background */
  LCD_SetTransparency(0);
 
  /* Set LCD Foreground Layer  */
  LCD_SetLayer(LCD_FOREGROUND_LAYER);
 
  /* Configure the transparency for foreground */
  LCD_SetTransparency(200);
 
  /* Clear the Foreground Layer */
  LCD_Clear(LCD_COLOR_WHITE);
 
  /* Set the LCD Back Color and Text Color*/
  LCD_SetBackColor(LCD_COLOR_BLUE);
  LCD_SetTextColor(LCD_COLOR_WHITE);
 
    /* Set the LCD Text size */
  LCD_SetFont(&FONTSIZE);
 
  LCD_DisplayStringLine(LINE(0x01), (uint8_t*)MSG1);
  LCD_DisplayStringLine(LINE(0x19), (uint8_t*)"                               ");
 
  /* Set the LCD Text size */
  LCD_SetFont(&Font16x24);
 
  /* Set the LCD Back Color and Text Color*/
  LCD_SetBackColor(LCD_COLOR_WHITE);
  LCD_SetTextColor(LCD_COLOR_BLUE);
}
 
 
/**
  * @brief  Display ADCs converted values on LCD
  * @param  None
  * @retval None
  */
static void Display(void){
  uint32_t a =0, b=0;
  uint8_t aTextBuffer[50];
  uint8_t i = 0;
 
  for(i=0; i<2; i++)
  {
      sprintf((char*)aTextBuffer, MSG3, ADCConvertedValue[i]);
      LCD_DisplayStringLine(LINE(1+i), (uint8_t*)aTextBuffer);
 
      ADCConvertedVoltage[i] = 3000 * ADCConvertedValue[i] / 0xFFF;
 
      a = (ADCConvertedVoltage[i])/1000;
      b = (ADCConvertedVoltage[i]%1000)/100;
      sprintf((char*)aTextBuffer, MSG2, a, b);
      LCD_DisplayStringLine(LINE(4+i), (uint8_t*)aTextBuffer);
  }
 
}
 
 
void pinout_config(void)
{
  GPIO_InitTypeDef      GPIO_InitStructure;
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
 
  GPIO_StructInit(&GPIO_InitStructure);
  ADC_StructInit(&ADC_InitStructure);
  ADC_CommonStructInit(&ADC_CommonInitStructure);
  DMA_StructInit(&DMA_InitStructure);
 
  /**
    Set up the clocks are needed for the ADC
  */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
 
  /**
    Initialization of the GPIO Pins [OK]
  */
 
  /* Analog channel configuration : PC.01, 02*/
  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);
 
  /**
    Configure the DMA
  */
  //==Configure DMA2 - Stream 4
  DMA_DeInit(DMA2_Stream4);  //Set DMA registers to default values
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; //Source address
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValue[0]; //Destination address
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 2; //Buffer size
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //source size - 16bit
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // destination size = 16b
  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_Stream4, &DMA_InitStructure); //Initialize the DMA
  DMA_Cmd(DMA2_Stream4, ENABLE); //Enable the DMA2 - Stream 4
 
   /**
     Config the ADC1
   */
   ADC_DeInit();
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
   ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //continuous conversion
   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
   ADC_InitStructure.ADC_NbrOfConversion = 2;
   ADC_InitStructure.ADC_ScanConvMode = ENABLE; // 1=scan more that one channel in group
   ADC_Init(ADC1,&ADC_InitStructure);
 
   ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
   ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
   ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
   ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
   ADC_CommonInit(&ADC_CommonInitStructure);
 
   ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_480Cycles);
   ADC_RegularChannelConfig(ADC1,ADC_Channel_12,2,ADC_SampleTime_480Cycles);
 
   ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
 
   ADC_DMACmd(ADC1, ENABLE); //Enable ADC1 DMA
 
   ADC_Cmd(ADC1, ENABLE);   // Enable ADC1
 
   ADC_SoftwareStartConv(ADC1); // Start ADC1 conversion
 
}




Outcomes