cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 ADC 2channels + DMA

tom23
Associate II
Posted on December 30, 2013 at 14:47

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
}

#hello-pleace-give-me-main.h-file #adc #dma #me-too #understand-your-tools #stm32f4-adc-dma #hello-please-help-me
27 REPLIES 27
lowpowermcu
Associate II
Posted on December 30, 2013 at 15:39

Hi Tomas,

Can you add 

ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE)

 after

 

ADC_RegularChannelConfig() 

and tell us if it changes the behavior.

tom23
Associate II
Posted on December 30, 2013 at 16:40

Hello,

It has no effect to sampling.

lowpowermcu
Associate II
Posted on December 30, 2013 at 16:43

Hi tomas,

can you check with scan mode disaled?
ADC_InitStructure.ADC_ScanConvMode=DISABLE;
// 1=scan more that one channel in group
tom23
Associate II
Posted on December 30, 2013 at 17:37

I tryed two cases with ADC_InitStructure.ADC_ScanConvMode = DISABLE

1) ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_480Cycles);

   ADC_RegularChannelConfig(ADC1,ADC_Channel_12,2,ADC_SampleTime_480Cycles);

Both items of ADCConvertedValue[] depend on PC1. 

2) ADC_RegularChannelConfig(ADC1,ADC_Channel_12,1,ADC_SampleTime_480Cycles);

   ADC_RegularChannelConfig(ADC1,ADC_Channel_11,2,ADC_SampleTime_480Cycles);

Both items of ADCConvertedValue[] does not depend on neither PC1 nor PC2. 

lowpowermcu
Associate II
Posted on December 30, 2013 at 18:44

Hi Tomas,

I have used the code below (it is similar to your initial code) for PC0 and PC1 and it is working fine.

I am suspecting your hardware platform. Which board/starter kit are you using?

 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_0 | GPIO_Pin_1;

  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_10,1,ADC_SampleTime_480Cycles);

   ADC_RegularChannelConfig(ADC1,ADC_Channel_11,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

tom23
Associate II
Posted on December 30, 2013 at 19:29

This code does not work on my STM32F429I-DISCO

Posted on December 30, 2013 at 22:05

Surely PC3 (Ch13) and PA5 (Ch5) would be a better choice of pins, being less conflicted?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
tom23
Associate II
Posted on December 30, 2013 at 23:44

Combination PC3+PA5 works correctly. Thank you very much!

 

I have tryed PC1+2, PC3+4, PA5+6 - and all these combination didnt work. Why? 

Posted on December 31, 2013 at 00:17

Why?

Probably because the two I suggested were carefully chosen based on the

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/DM00093903.pdf

, and the other ones you've picked are connected to other circuitry. The aren't may choices here that will work.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..