cancel
Showing results for 
Search instead for 
Did you mean: 

Storing ADC values into an array

jf659
Associate II
Posted on February 05, 2014 at 13:41

Hello,

I'm currently getting ADC values and storing them into an array, incrementing the array after storing each value. I want to make the array quite large, but the program crashes if i go above array[500]. During debug the program jumps to a hard fault handler. Am i not allowed to create arrays this big? Here is my code:

/************************************************************************** 
RCC configuration for ADCs and GPIO 
***************************************************************************/ 
void RCC_Configuration(void) 
{ 
/* Enable peripheral clocks */ 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE); 
} 
/************************************************************************** 
GPIO configuration 
***************************************************************************/ 
void GPIO_Configuration(void) 
{ 
GPIO_InitTypeDef GPIO_InitStructure; 
/* Configure ADC Channel 12 pin as analog input */ 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_1; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; 
GPIO_Init(GPIOC, &GPIO_InitStructure); 
} 
/************************************************************************** 
Initialize the ADC, ADCs interface clock, pin 
***************************************************************************/ 
void config_ADC(void) 
{ 
/* Strucutre definitions */ 
ADC_InitTypeDef ADC_InitStructure; 
ADC_CommonInitTypeDef ADC_CommonInitStructure; 
RCC_Configuration(); 
GPIO_Configuration(); 
/* ADC Common Init */ 
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; 
/* the RCC clock uses HCclk/2 = 168MHz/2 = 84MHz/prescaler */ 
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8; 
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; 
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; 
ADC_CommonInit(&ADC_CommonInitStructure); 
/* ADC1 regular channel 12 configuration */ 
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_DataAlign = ADC_DataAlign_Right; 
ADC_InitStructure.ADC_NbrOfConversion = 1; 
ADC_Init(ADC1, &ADC_InitStructure); 
ADC_Init(ADC2, &ADC_InitStructure); 
/* Set up the channel for ADC1 PC2*/ 
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_480Cycles); 
/* Set up the channel for ADC 2 PC1 */ 
ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_3Cycles); 
/* Enable interrupt */ 
//ADC1->CR1 |= ADC_CR1_EOCIE; 
/* enable the interrupt */ 
//NVIC_EnableIRQ(ADC_IRQn); 
/* Enable ADC1 and ADC2*/ 
ADC_Cmd(ADC1, ENABLE); 
ADC_Cmd(ADC2, ENABLE); 
} 
/************************************************************************** 
Read the ADC 1 value 
***************************************************************************/ 
int read_ADC1(void) 
{ 
float ADC1ConvertedValue = 0; 
/* Start ADC3 Software Conversion */ 
ADC_SoftwareStartConv(ADC1); 
/* Wait unti lthe conversion is done */ 
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); 
/* Get the converted value */ 
ADC1ConvertedValue = ADC_GetConversionValue(ADC1); 
return ADC1ConvertedValue; 
}

In main i then call a function called measure_acoustic();

/******************************************************************************** 
Function to measure acoustics 
*********************************************************************************/ 
#define BUFFERSIZE 900 
void measure_acoustic(void) { 
int i; 
int noConversions = BUFFERSIZE; 
uint16_t acoustic_sample[BUFFERSIZE]; 
for(i = 0; i < noConversions; i++){ 
acoustic_sample[i] = read_ADC1(); 
} 
printf(''SUCCESS\r\n''); 
}

Can anyone help me, or know why i can't use large arrays. Or is there a different way to store a large number of values. Thanks
8 REPLIES 8
frankmeyer9
Associate II
Posted on February 05, 2014 at 13:50

void measure_acoustic(void) {

int i;

int noConversions = BUFFERSIZE;

uint16_t acoustic_sample[BUFFERSIZE]; . . .

Defining variables (and arrays, for that matter), places them on the stack, which is limited in size, and used dynamically by function calls and interrupts. Thus you end up in the hardfault handler.

Either increase the stack size (you seem to have 1kByte at the moment...), or define you array outside of any function (preferably as

static

to avoid polluting global name space).

jf659
Associate II
Posted on February 05, 2014 at 14:16

Thanks, that seemed to work for values array sizes of upto 60,000. But i get these errors when i try anything bigger:

Error: L6406E: No space in execution regions with .ANY selector matching project.o(.bss).

Error: L6407E: Sections of aggregate size 0x30d40 bytes could not fit into .ANY selector(s).

I want to store 660KB, which would be a 30 second sample at 22 kHz sample rate, 8 bit resolution.

trevor23
Associate III
Posted on February 05, 2014 at 14:24

What processor part number, how much RAM does it have? I suspect it has much less than 660KB of RAM

jf659
Associate II
Posted on February 05, 2014 at 14:37

It is the STM32F407VG board. Yes it only has 192 KB of RAM. Is there a way of storing this array in flash memory, which there is 1MB?

francescatodiego
Associate II
Posted on February 05, 2014 at 15:46

Read also the fsmc peripheral - you can add one external SRAM

Posted on February 05, 2014 at 16:07

It is the STM32F407VG board. Yes it only has 192 KB of RAM. Is there a way of storing this array in flash memory, which there is 1MB? 

No, not really. Better to pick a board/processor appropriate for your project's needs. In the STM32 family, the

http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090

board has an 8MB SDRAM.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jf659
Associate II
Posted on February 05, 2014 at 16:14

Ok, I am using the STM32F407 board with the expansion board. Would it be possible to store the samples straight to external memory such as an SD card?

Posted on February 05, 2014 at 16:30

Perhaps, I've posted ADC to MicroSD sampling examples for the STM32F4-DIS-BB before.

It's not going to go ''straight'' anywhere, the ADC must DMA into RAM, and then you'd need to manage/buffer the data stream to a file via a file system, and SDIO card driver.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..