Other Parts Discussed in Thread: MSP430F5529
Hello,
My name is William.
I am writing a code for a datalogger using the internal ADC (12 bits) of the MSP430F5529 LaunchPad. My goal is to get the samples and fill an array (a buffer) then store these samples in the sd card, and repeat the process (acquire samples ; fill buffer ; store onto micro SD Card). I am using the FatFs library.
Before to trying store the different samples onto the sd, I wrote equal samples (just the first one) with a loop and a interruption service routine by timer (10seconds), to measure the performance of the saving, reaching good speeds when the array size was set to 1024 (2048 bytes - array of short int).
The problem happens when I put the get_adc function inside the loop. If I set the array size as large as when the get_adc function was before the file initialization, the file is opened but the MSP doesn't write anything on it. It just works with small arrays (size around 50) with bad performance (too slow).
I checked the memory allocation in the CCS and the RAM use sounds good to me (around 10%).
Do you think the facts I am putting the microcontroller at Low Power Mode (LPM0) and using an interruption in the sample acquiring routine may affect the file that was opened before even if the stack data are restored after coming back from ISR?
Below is the code of the ADC samples acquiring. The main function is not here but it basically opens the file, and goes into a while loop that calls the adc functions to get the actual sample and writes into the SD Card while the timer overflow didn't happen. When the timer counter overflows, an ISR is called, closing the file and unmounting the card.
Thank you in advance.
ADC CODE:
#include <adc.h>
#include <stdio.h>
#include "funcoes.h"
unsigned short int indiceVetor; /* indice para o vetor de resultados */
int adc_init(void)
{
unsigned short int contador;
indiceVetor = 0;
for(contador=0;contador < COMPRIMENTO_VETOR_RESULTADOS;contador++)
{
vetorResultados[contador] = 0;
}
/* Setting Pin 6.0 as ADC Input */
GPIO_setAsPeripheralModuleFunctionOutputPin(
GPIO_PORT_P6,
GPIO_PIN0
);
// Initialize ADC12 with ADC12’s built-in oscillator
ADC12_A_init (ADC12_A_BASE, ADC12_A_SAMPLEHOLDSOURCE_SC, ADC12_A_CLOCKSOURCE_ADC12OSC, ADC12_A_CLOCKDIVIDER_1);
//Switch ON ADC12
ADC12_A_enable(ADC12_A_BASE);
// Setup sampling timer to sample-and-hold for 16 clock cycles
ADC12_A_setupSamplingTimer (ADC12_A_BASE,
ADC12_A_CYCLEHOLD_64_CYCLES,
ADC12_A_CYCLEHOLD_4_CYCLES,
ADC12_A_MULTIPLESAMPLESDISABLE); /* atenção */
// Configure the Input to the Memory Buffer with the specified Reference Voltages
ADC12_A_configureMemoryParam param = {0};
param.memoryBufferControlIndex = ADC12_A_MEMORY_0;
param.inputSourceSelect = ADC12_A_INPUT_A0;
param.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC;
param.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS;
param.endOfSequence = ADC12_A_NOTENDOFSEQUENCE;
ADC12_A_configureMemory(ADC12_A_BASE ,¶m);
ADC12_A_setReferenceBufferSamplingRate(ADC12_A_BASE, ADC12_A_MAXSAMPLINGRATE_200KSPS);
ADC12_A_clearInterrupt(ADC12_A_BASE, ADC12IFG0);
ADC12_A_enableInterrupt(ADC12_A_BASE, ADC12IE0);
return 0;
}
int get_adc (void)
{
while (1)
{
// Start a single conversion, no repeating or sequences.
ADC12_A_startConversion (ADC12_A_BASE,
ADC12_A_MEMORY_0,
ADC12_A_SINGLECHANNEL);
// Wait for the Interrupt Flag to assert at LPM0
__bis_SR_register(LPM0_bits + GIE);
if(indiceVetor <= COMPRIMENTO_VETOR_RESULTADOS)
{
vetorResultados[indiceVetor] = resultadoGlobal;
indiceVetor++;
}
else
{
return 0;
}
ADC12_A_clearInterrupt(ADC12_A_BASE,ADC12IFG0);
}
}
#pragma vector=ADC12_VECTOR
__interrupt void ADC12_A_ISR(void) /* Flag ADC12IFG0 gerou a interrupção, indicando que deve ser executada ISR ADC_A_ISR */
{
switch(__even_in_range(ADC12IV,34))
{
case 0: break; //Vector 0: No interrupt
case 2: break; //Vector 2: ADC overflow
case 4: break; //Vector 4: ADC timing overflow
case 6: //Vector 6: ADC12IFG0
resultadoGlobal = (ADC12_A_getResults(ADC12_A_BASE,ADC12_A_MEMORY_0)); /* pegando os resultados e colocando na variável temporária de resultado */
//Exit active CPU
__bic_SR_register_on_exit(LPM0_bits);
break;
case 8: break; //Vector 8: ADC12IFG1
case 10: break; //Vector 10: ADC12IFG2
case 12: break; //Vector 12: ADC12IFG3
case 14: break; //Vector 14: ADC12IFG4
case 16: break; //Vector 16: ADC12IFG5
case 18: break; //Vector 18: ADC12IFG6
case 20: break; //Vector 20: ADC12IFG7
case 22: break; //Vector 22: ADC12IFG8
case 24: break; //Vector 24: ADC12IFG9
case 26: break; //Vector 26: ADC12IFG10
case 28: break; //Vector 28: ADC12IFG11
case 30: break; //Vector 30: ADC12IFG12
case 32: break; //Vector 32: ADC12IFG13
case 34: break; //Vector 34: ADC12IFG14
default: break;
}
}