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
sunilkasar7
Associate II
Posted on September 14, 2015 at 15:15

with the help of a pot I am varying ADC input. I have connected one pin of pot to 3V, second to ground and one more to one ADC channel. and when I change voltage at one pin of channel, it is effecting other 3 channel results also.

sunilkasar7
Associate II
Posted on September 14, 2015 at 15:36

@clive,

I have configured PA0,PA1,PA2 and PA4 pins for ADC channels.

1. When I connect POT at PA0 and vary the voltage, all other 3 pin's voltage too getting varied.

2. When I connect POT to PA1, and vary voltage, voltage at PA2 and PA3 too getting varied. And Voltage at PA0 is unaffected.

3. When I connect POT to PA2 and vary voltage, the voltage at PA3 too getting varied. And voltage at PA0 and PA1 is unaffected.

4. When I connect POT to PA3 and vary voltage, the voltage at PA3 is getting varied and rest are fine(unaffected).

Can you figure out why is this happening? I have attached code for your convenience.

Thanking you.

sunilkasar7
Associate II
Posted on September 14, 2015 at 15:43

@ clive,

In previous post, Replace PA3 for PA4.

I haven't configured PA4 for ADC. It's typing mistake.

Thanking you.

raptorhal2
Lead
Posted on September 14, 2015 at 16:00

This result is normal. The unconnected pins are floating and responding to crosstalk from the pot signal pin. Put a low impedance signal concurrently on all 4 pins and the ''problem'' should magically disappear.

This is assuming that the other pins are not already connected to something, which is why you were asked to identify the type of board.

Cheers, Hal

Posted on September 14, 2015 at 16:56

Can you figure out why is this happening? I have attached code for your convenience.

Understand my interest in ADC code is marginal. Your code example is incomplete, as is I can't compile it with some effort. I don't know what chip you're using, nor what board, and if I have that board. Some of the pins are probably used for other things on the STM32F4-DISCO. You have some odd delaying functions which stop you printing out contemporaneous values for all (4) channels. I would suggest you tie all the unused pins to Ground or 3V and see if that changes how the POT's value is output. Ideally put POTs on all the pins. Think of the sample-and-hold as a capacitor, if there's no current flow, or adequate flow, to charge/discharge the capacitor it's going to stay roughly where it is.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
sunilkasar7
Associate II
Posted on September 15, 2015 at 09:57

Hi

baird.hal and Clive,

Thank you for your suggestions.

I connected PA0 to POT, and  PA1,PA2, PA3 to 3V. It is working fine.

Once again thanks a lot.

galamat
Associate II
Posted on November 13, 2015 at 18:32

Hi, Clive!

I see that you a lot about STM32 micro controllers. Can ADC work without NVIC and DMA? 

Posted on November 13, 2015 at 19:25

Technically yes, practically less so.

You can use the ADC in a single channel mode with polling, when you get to multiple channels you need to use DMA to manage the data into specific memory slots. The conversions can occur at a rate that exceeds your ability to service them usefully.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..