cancel
Showing results for 
Search instead for 
Did you mean: 

wrong values- adc with dma

arunl4g
Associate II
Posted on July 14, 2015 at 09:48

#include <stm32f4xx.h>

#include <stm32f4xx_conf.h>

i have posted the code below and i get wrong value. Can anyone tell me whats wrong ?

volatile uint16_t Buffer[12];

uint8_t receiveword;

/* ADC Configuration */

void adcConfig()

{

//clock for leds

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

//GPIO intialization for leds

GPIO_InitTypeDef GPIO_IntStruct;

GPIO_IntStruct.GPIO_Mode = GPIO_Mode_OUT;

GPIO_IntStruct.GPIO_OType = GPIO_OType_PP ;

GPIO_IntStruct.GPIO_Pin = GPIO_Pin_12 |GPIO_Pin_13 |GPIO_Pin_14 |GPIO_Pin_15;

GPIO_IntStruct.GPIO_PuPd = GPIO_PuPd_UP ;

GPIO_IntStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOD, &GPIO_IntStruct);

/******************** PA1 - channel1 --data sheet page number 48*******************/

//clock for PA1

RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);

//GPIO init

GPIO_InitTypeDef GPIO_InitStructure;

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);

//clock for dma --------page number 308 ----channel 0 and stream 0

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

DMA_DeInit(DMA2_Stream0);

DMA_InitTypeDef DMA_InitStruct;

DMA_InitStruct.DMA_Channel = DMA_Channel_0;

DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory; // Receive

DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)Buffer;

DMA_InitStruct.DMA_BufferSize = (uint16_t)sizeof(Buffer);

DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;

DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;;

DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;

DMA_InitStruct.DMA_Priority = DMA_Priority_High;

DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;

DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;

DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

DMA_Init(DMA2_Stream0, &DMA_InitStruct);

//enable dma2

DMA_Cmd(DMA2_Stream0, ENABLE);

//clock

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

//clock for the port ------------- i dont think its needed.

RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN, ENABLE);

//common init configuration

ADC_CommonInitTypeDef ADC_CommonInitStruct;

ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;

ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2;

ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

ADC_CommonInit(&ADC_CommonInitStruct);

//config init

ADC_InitTypeDef ADC_InitStructure;

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

ADC_InitStructure.ADC_ScanConvMode = DISABLE;

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;

ADC_InitStructure.ADC_NbrOfConversion = 1;

ADC_Init(ADC1, &ADC_InitStructure);

//samplign time config

ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);

//dma request

ADC_DMACmd(ADC1, ENABLE);

//enable adc

ADC_Cmd(ADC1, ENABLE);

}

/**************************************************************************************/

int main(void)

{

adcConfig();

int i ;

ADC_SoftwareStartConv(ADC1);

while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Processing the conversion

if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == SET)

{

GPIO_SetBits(GPIOD, GPIO_Pin_13);

for (i = 0; i < 20; i++)

{

printf(''%d\n'', Buffer[i]);

}

}

return 0;

}

18 REPLIES 18
Posted on July 22, 2015 at 21:01

clive, can you tell me how the dma is 24?... according to my knowledge, the buffer size is the dma size... if not correct can u tell me how its

volatile uint16_t Buffer[12];
..
DMA_InitStruct.DMA_BufferSize = (uint16_t)sizeof(Buffer); // sizeof returns a BYTE count for the array, ie 24
..
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // count is in units of 16-bit HalfWords
..
for (i = 0; i < 20; i++)
{
printf(''%d
'', Buffer[i]);
}
#define ELEMENTS 12
volatile uint16_t Buffer[ELEMENTS];
..
DMA_InitStruct.DMA_BufferSize = ELEMENTS;
..
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Buffer[] is composed of 16-bit HalfWords
..
for (i = 0; i < ELEMENTS; i++)
{
printf(''%d
'', Buffer[i]);
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jpeacock
Associate III
Posted on July 22, 2015 at 21:34

Are you sure 3 cycles is enough time for the conversion?  What is your sample and hold circuit?  Too short a conversion time and you get mostly random results.  Try it with a slow time first, and then shorten it until you get a good conversion time.  The ADC section in the RM explains the setup requirements before sampling.

  Jack Peacock

arunl4g
Associate II
Posted on July 23, 2015 at 09:53

thank you clive..ur explanation helps me to learn.

i would like to about fifo. i have '' enabled FIFO and the threshold is full '', so it means 4 * word(32 bit) for FIFo full according to manual. how FIFO  works here?

Could you give some explanation ?
jpeacock
Associate III
Posted on July 23, 2015 at 14:18

The FIFO reduces memory bus contention by buffering samples into the FIFO before writing them to memory in a burst.  There's less contention with the CPU and other DMA controllers when performing a single bus transaction write of 4 sequential words instead of four transactions of one word.  This is significant with large, high speed DMA transfers.

With one ADC each FIFO sample is 16 bit, so it only uses half the 32 bit FIFO word.  The FIFO is 4 words long so you can buffer 4 samples.  With both ADCs paired you convert two samples (ADC1 and ADC2) into a 32 bit word at the same time, making full use of the FIFO.  The DMA has to be word aligned to match the space used in a FIFO word (i.e. align at full word boundary for paired ADC samples, half word for single ADC).

The threshold is useful when manually triggering DMA with tight buffer boundaries.  The early warning when DMA will over/under flow allows you to set up more data for the DMA controller on a manual basis.

The FIFO can also pack and unpack different word sizes.  This gets complicated with word alignment but is very useful for certain types of DMA such as large transfers over a serial port.

  Jack Peacock
arunl4g
Associate II
Posted on July 24, 2015 at 09:06

clive, i am not understanding why buffer size has to be 12 bytes, why not 24 bytes. what impack it can make if its 12 bytes and what hapepns if its 24 bytes?

Posted on July 24, 2015 at 09:29

DMA_BufferSize is *NOT* a byte count, it's a transfer count in UNITS of size described in the Memory and Peripheral DataSize (width) fields.

If you tell it to write over a larger memory space than the array covers will result in the DMA HARDWARE corrupting surrounding memory variables and structures, beyond the scope of the memory you want it touching.

You understand why that would be a BAD THING? Right?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 24, 2015 at 09:34

In the code I pasted yesterday, I contrasted the way you described the array in three inconsistent ways (which I pointed out in a prior response), with the uniform way you might do it to avoid picking the wrong size at each opportunity.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
arunl4g
Associate II
Posted on July 24, 2015 at 14:08

understand perfect.. thank you 

i would like to know one more thing that, 

1. time difference between two samples(12 bits, 3 cycles sampling time) = conversion time (15 cycles)+ 5 cycles (''ADC_TwoSamplingDelay_5Cycles'' )..

is that correct?..

2. In adc configuration, whats the need of using '' ADC_InitStructure.ADC_NbrOfConversion = 1; '' ?...

i would like to know one more thing that, 

1. time difference between two samples(12 bits, 3 cycles sampling time) = conversion time (15 cycles)+ 5 cycles (''

ADC_TwoSamplingDelay_5Cycles'' )..

is that correct?..

2. In adc configuration, whats the need of using '' 

ADC_InitStructure.ADC_NbrOfConversion = 1; '' ?...

Posted on July 24, 2015 at 14:43

1) I think it's just 15 cycles of the ADC prescaled clock. To confirm you could do 1000 samples and toggle a GPIO, and measure the period on a scope.

2) You are building an enumerate list of channels that can be scanned. You have just ONE, and it doesn't need to be scanned. At each trigger event it scans and converts the listed channels. In continuous mode every set completes and it retriggers.

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