2014-12-30 05:47 AM
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
2014-12-30 06:39 AM
Hi Tomas,
Can you add ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE) afterADC_RegularChannelConfig()
and tell us if it changes the behavior.2014-12-30 07:40 AM
Hello,
It has no effect to sampling.2014-12-30 07:43 AM
Hi tomas,
can you check with scan mode disaled?ADC_InitStructure.ADC_ScanConvMode=DISABLE;
// 1=scan more that one channel in group
2014-12-30 08:37 AM
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.2014-12-30 09:44 AM
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 conversion2014-12-30 10:29 AM
This code does not work on my STM32F429I-DISCO
2014-12-30 01:05 PM
Surely PC3 (Ch13) and PA5 (Ch5) would be a better choice of pins, being less conflicted?
2014-12-30 02:44 PM
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?2014-12-30 03:17 PM
Why?
Probably because the two I suggested were carefully chosen based on thehttp://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.