cancel
Showing results for 
Search instead for 
Did you mean: 

One channel ADC and DMA - Not working?

dawnofapril10
Associate II
Posted on October 13, 2015 at 11:19

Hi.I am trying to move one channel ADC value into DMA and read it in main.However its not working.What could be wrong??

/*Preprocessor Directives*/
#include <
stm32f0xx_adc.h
>
#include <
stm32f0xx_gpio.h
>
#include <
stm32f0xx_rcc.h
>
#include <
stm32f0xx_dma.h
>
/*Peripheral address directives*/
#define ADC1_DR_Address 0x40012440
/*Variables declaration*/
static unsigned int ADC_val; /*12-bit value*/
//uint16_t RegularConvData_Tab[2]; /*RegularConvData_Tab[0],[1]*/
/*Function Prototype declaration*/
void init_ADC(void);
void init_DMA(void);
int main(void)
{
init_DMA();
init_ADC();
while(1)
{ 
/* Test DMA1 TC flag */
while((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET);
/* Clear DMA TC flag */
DMA_ClearFlag(DMA1_FLAG_TC1);
if (ADC_val > 1000)
{
GPIOC->BSRR = GPIO_Pin_8;
GPIOC->BSRR = GPIO_Pin_9;
GPIOC->BSRR = GPIO_Pin_7;
}
else
{
GPIOC->BRR = GPIO_Pin_8;
GPIOC->BRR = GPIO_Pin_9;
GPIOC->BRR = GPIO_Pin_7;
}
}
}
void init_ADC()
{
GPIO_InitTypeDef GPIO_InitStructure; 
ADC_InitTypeDef ADC_InitStructure; 
/*Setup a systick interrupt every 1ms (1/1000 seconds)*/
SysTick_Config(SystemCoreClock/1000);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_Init(GPIOC, &GPIO_InitStructure); 
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; 
GPIO_Init(GPIOA, &GPIO_InitStructure); 
ADC_DeInit(ADC1); 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 
ADC_StructInit(&ADC_InitStructure); 
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; 
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;disabled */
//ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO; 
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward; 
ADC_Init(ADC1, &ADC_InitStructure); 
ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_28_5Cycles); 
ADC_GetCalibrationFactor(ADC1); 
//ADC_WaitModeCmd(ADC1, ENABLE); 
//ADC_AutoPowerOffCmd(ADC1, ENABLE); 
ADC_Cmd(ADC1, ENABLE); 
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); 
ADC_StartOfConversion(ADC1); 
}
void init_DMA()
{
DMA_InitTypeDef DMA_InitStructure; 
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE); 
DMA_DeInit(DMA1_Channel1); 
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)ADC1_DR_Address; 
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_val; 
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
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);
DMA_Cmd(DMA1_Channel1, ENABLE); 
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); 
ADC_DMACmd(ADC1, ENABLE); 
}
/*Preprocessor Directives*/
#include <stm32f0xx_adc.h>
#include <stm32f0xx_gpio.h>
#include <stm32f0xx_rcc.h>
#include <stm32f0xx_dma.h>
/*Peripheral address directives*/
#define ADC1_DR_Address 0x40012440
/*Variables declaration*/
static
unsigned 
int
ADC_val; 
/*12-bit value*/
//uint16_t RegularConvData_Tab[2]; /*RegularConvData_Tab[0],[1]*/
/*Function Prototype declaration*/
void
init_ADC(
void
);
void
init_DMA(
void
);
int
main(
void
)
{
init_DMA();
init_ADC();
while
(1)
{ 
/* Test DMA1 TC flag */
while
((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET);
/* Clear DMA TC flag */
DMA_ClearFlag(DMA1_FLAG_TC1);
if
(ADC_val > 1000)
{
GPIOC->BSRR = GPIO_Pin_8;
GPIOC->BSRR = GPIO_Pin_9;
GPIOC->BSRR = GPIO_Pin_7;
}
else
{
GPIOC->BRR = GPIO_Pin_8;
GPIOC->BRR = GPIO_Pin_9;
GPIOC->BRR = GPIO_Pin_7;
}
}
}
void
init_ADC()
{
GPIO_InitTypeDef GPIO_InitStructure; 
/*GPIO*/
ADC_InitTypeDef ADC_InitStructure; 
/*ADC*/
/*Setup a systick interrupt every 1ms (1/1000 seconds)*/
SysTick_Config(SystemCoreClock/1000);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_Init(GPIOC, &GPIO_InitStructure); 
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; 
GPIO_Init(GPIOA, &GPIO_InitStructure); 
/*Initialize typedef*/
ADC_DeInit(ADC1); 
/*De-Initialize ADC (RESET)*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 
ADC_StructInit(&ADC_InitStructure); 
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; 
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
//ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO; 
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward; 
ADC_Init(ADC1, &ADC_InitStructure); 
ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_28_5Cycles); 
ADC_GetCalibrationFactor(ADC1); 
//ADC_WaitModeCmd(ADC1, ENABLE); 
//ADC_AutoPowerOffCmd(ADC1, ENABLE); 
ADC_Cmd(ADC1, ENABLE); 
/*Enable ADC1 Core*/
while
(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); 
ADC_StartOfConversion(ADC1); 
/*Start conversion*/
}
void
init_DMA()
{
DMA_InitTypeDef DMA_InitStructure; 
/*DMA typedef*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE); 
/* DMA1 clock enable */
DMA_DeInit(DMA1_Channel1); 
/*Disable and reset*/
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)ADC1_DR_Address; 
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_val; 
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
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);
DMA_Cmd(DMA1_Channel1, ENABLE); 
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); 
ADC_DMACmd(ADC1, ENABLE); 
/*Enable ADC-DMA*/
}

#stm32f0 #adc #dma
4 REPLIES 4
Posted on October 13, 2015 at 14:14

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_val; 

You want the ADDRESS of the variable, not the CONTENT, so &ADC_val
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dawnofapril10
Associate II
Posted on October 15, 2015 at 04:04 Hi Clive, Thanks for pointing that out.However in main,it gets stuck here (during debugging) >

/* Test DMA1 TC flag */
while
((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET);

Should i avoid circular and use normal mode?
Posted on October 15, 2015 at 06:29

You should probably enable the clocks up front, and review the order you do things, as it is you touch the ADC in the DMA init routine before you've enabled and configured the ADC.

I might opt to make the buffer bigger, pretty sure I've posted an ADC+DMA example

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mats239955_st
Associate
Posted on December 08, 2015 at 12:07

It looks like you are configuring the ADC_DMACmd before enabling the clock to the ADC so there is actually no connection between the peripherals.

Even the ADC_DeInit is done before the ADC clock is running.

Suggest to enable both DMA and ADC clocks before configuration.