Hi,
I am trying to read two channels, P1.0 and P1.3, in a msp430g2553. I have configured the ADC10 in repeat secuence channels mode. I want to read this two channels in a block of 40 samples ( 4 channels x 10 secuences) , next calculate the avg of each channel and show it in a LCD pannel, all of this repeatedly. The two signals to sample are sinusoidal signals.
1. The first problem is that the buffer area for the samples is not exclusive for this. When I debugg and show the memory 0x200 I see other variables and then its are overwritten. How it made for what the variables aren't in the buffer zone of the ADC? I have tried to assign them to another memory area, eg 0x1000, but nothing is saved and the device is reset.
2. If I want to increment the number of samples to 240 conversions, then the device is reset to the second o third block conversion. I noticed that in position memory 0x3b0 appears the label "_stack". What is this, I can not access those positions??
Error: program will not fit into available memory. run placement with alignment fails for section ".stack" size 0x50 . Available memory ranges: lnk_msp430g2553.cmd
If my buffer is defined with array of 100 positions, the error does not appear.
3. How I can make my variable is assigned to the position of 0x200 memory?
This is part of my code:
unsigned char capture=0; unsigned char ADCDone=0; unsigned int sumV,sumI,instP,sumP; long lastFilteredV,filteredV; long lastFilteredI, filteredI; volatile unsigned int buf_adc[50]; const unsigned char NSAMPLES = 48; int main(void) { unsigned char start=0; WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer //Setup Clocks DCOCTL = CALDCO_1MHZ; //Internal oscillators frequency BCSCTL1 = CALBC1_1MHZ; BCSCTL1 |= DIVA_1; // ACLK/8 - wake up about every 26 seconds (WHEN DIVA_3 - about 6 seconds for DIV 1) BCSCTL2 = DIVS_0; // SMCLK = DCOCLK/0 - SPI (USCI) uses SMCLK, prefer SMCLK < 10MHz (SPI speed limit for nRF24 = 10MHz) BCSCTL3 |= LFXT1S_2; // ACLK = VLO while (BCSCTL3 & LFXT1OF) ; // Wait until the VLOCLK is up, running & stable start = 1; lcdi2c(0x27, 20, 4); //Assign address LCD and type init(); //Init i2c bus and lcd backlight(); //Switch on LCD ConfigureAdc(); __bis_SR_register(GIE); // interrupts enabled while(1) { if (start) { ADC10CTL0 &= ~ENC; while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled start = 0; } //Calculamos la suma if (ADCDone) { Calculo(); //Show vars in the LCD //... ADCDone = 0; capture = 1; } if (capture== 1) { ADC10SA = (unsigned int) &buf_adc; //Dir Inicio ADC10DTC0 |= ADC10CT; //Modo LPM0 __bis_SR_register(CPUOFF + GIE); // LPM0, the ADC interrupt will wake the processor up. capture = 0; } } return 0; } void ConfigureAdc(void) { /* Configure ADC Channel */ ADC10CTL1 = INCH_3 + ADC10DIV_1 + ADC10SSEL_3 + CONSEQ_3; // Channel 43210, ADC10CLK, SMCLK, Repeat varios CH ADC10CTL0 = REFOUT + REFON + ADC10SHT_3 + MSC + ADC10ON + ADC10IE; // ADC10CTL0 &= ~REF2_5V; // 1.5V Reference ADC10AE0 |= BIT0 + BIT3; //P1.0 + P1.3 ADC option ADC10DTC0 &= ~ADC10TB; //Mode ONE BLOCK TRANSFER ADC10DTC1 = 48; //Values to save = 48 samples (12 samples x channel) ADC10SA = (unsigned int) &buf_adc; //Dir Ini ADC10DTC0|=ADC10CT; // } void Calculo(void) { volatile unsigned int positiveV,positiveI; volatile unsigned int lastSampleV; //sample_ holds the raw analog read value, lastSample_ holds the last sample volatile unsigned int lastSampleI; volatile float VRATIO, IRATIO; unsigned char i; lastSampleI = buf_adc[0]; lastSampleV = buf_adc[3]; lastFilteredV = filteredV; //Used for offset removal lastFilteredI = filteredI; //Used for offset removal //Sumatorio for (i=0; i < NSAMPLES; i++) { filteredV = 1 *(lastFilteredV+ (int)(buf_adc[(i*4) + 3]-lastSampleV)); filteredI = 1 *(lastFilteredI+ (int)(buf_adc[i*4]-lastSampleI)); if (filteredV < 0) { positiveV = ~filteredV +1; sumV += positiveV; } else sumV += filteredV; if (filteredI < 0) { positiveI = ~filteredI +1; sumI += positiveI; } else sumI += filteredI; lastSampleI = buf_adc[i*4]; lastSampleV = buf_adc[(i*4) + 3]; } //Calculo VIP //... //Reset accumulators sumV = 0; sumI = 0; sumP = 0; } // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { ADC10DTC0 &= ~ADC10CT; //Stop sample & conversion //If you want come back to begin the samples, ADC10CT =1 ADCDone = 1; __bic_SR_register_on_exit(CPUOFF); // Return to active mode }
Thanks.