2015-10-13 02:19 AM
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
2015-10-13 05:14 AM
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_val;
You want the ADDRESS of the variable, not the CONTENT, so &ADC_val
2015-10-14 07:04 PM
/* Test DMA1 TC flag */
while
((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET);
Should i avoid circular and use normal mode?
2015-10-14 09:29 PM
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 example2015-12-08 03:07 AM
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.