I have a problem using MSP430i2041 in continuous mode. I am using the 4 SD channel with infrared sensor. I want to do 4 conversion, mean them, stop conversion during ~250ms using watchdog timer and after those 250 ms start again 4 conversion. Therefore, I want to start 4 conversion every 250ms. The problem is if I stop conversion using SD24CCTL0 &= ~SD24SC after the 4 conversions were done, it gives less accurate value than using disable interrupt without stopping conversion. When using disable interrupt it consumes much more power than when using stop conversion because conversion continue when the MSP is in sleep mode.
Why the result are less accurate using stop conversion? Is it possible to have a better accuracy? And why digital result have another mean value in term of all result compare with disabling interrupt?
Attach there is 2 graph that show result using stop conversion or disable interrupt, to show the accuracy the first ~200 values are when there is no movement and the following one are when there is movement. When there is no movement, the difference between 2 following value should be low and when there is movement the different should be higher. (the x axis is the conversion number and the y axis is the value of the adc. when there is 2 axis the one on the left is for sensor 0 and on the right sensor 1.
And here is my code. (I used example code in order to get directly the startup code because when I try to had to my code low_level_init.c it was stack on the CRC control.
#include "driverlib.h"
#include <stdlib.h>
#define Num_of_Results 4
/* Arrays to store SD24 conversion results */
uint32_t Ch0results[Num_of_Results];
uint32_t Ch1results[Num_of_Results];
uint32_t Ch2results[Num_of_Results];
uint32_t Ch3results[Num_of_Results];
//mean result of each sensors
uint32_t downLeftResultMean;
uint32_t upLeftResultMean;
uint32_t upRightResultMean;
uint32_t downRightResultMean;
//array of the 4 sensor (down left => 0, down right => 1, up left => 2, up right => 3
uint32_t diffSensor[4];
uint16_t index = 0;
void main(void) {
eaceP1DIR = 0xFF; // set all pin as output direction to save power
P1OUT = 0x00;
P2DIR = 0xFF; //set all pin as output direction to save power
P2OUT = 0x00;
CSCTL0 = DCOR;
// Stop WDT
WDTCTL = WDTPW | WDTHOLD; // Stop Watchdog Timer
// Configure interval to ACLK / 32k ~= 1s
WDTCTL = WDT_ADLY_1000;
WDT_resetTimer(WDT_BASE);
// Internal ref
SD24_init(SD24_BASE, SD24_REF_INTERNAL);
//Group with Channel 0
SD24CCTL0 = SD24DF | SD24GRP; //continuous mode, grouped, over sampling 256, format 2nd complement
SD24INCTL0 = SD24INCH_0 | SD24GAIN_1; // 4th sample interrupt, gain 4, differential pair input
//Group with Channel 1
SD24CCTL1 = SD24DF | SD24GRP; //continuous mode, grouped, over sampling 256, format 2nd complement
SD24INCTL1 = SD24INCH_1 | SD24GAIN_1; // 4th sample interrupt, gain 4, differential pair input
//Group with Channel 2
SD24CCTL2 = SD24DF | SD24GRP; //continuous mode, grouped, over sampling 256, format 2nd complement
SD24INCTL2 = SD24INCH_2 | SD24GAIN_1; // 4th sample interrupt, gain 4, differential pair input
// Enable interrupt
SD24CCTL3 = SD24DF | SD24IE; //continuous mode, grouped, over sampling 256, format 2nd complement
SD24INCTL3 = SD24INCH_3 | SD24GAIN_1; // 4th sample interrupt, gain 4, differential pair input
// Configure MCLK, SMCLK = ~1MHz
CSCTL1 |= DIVM__16 | DIVS__16;
WDTCTL = WDT_ADLY_250;
// Start the WDT and enter LPM3 with interrupts enabled
SFR_clearInterrupt(SFR_WATCHDOG_INTERRUPT);
SFR_enableInterrupt(SFR_WATCHDOG_INTERRUPT);
WDT_start(WDT_BASE);
__bis_SR_register(LPM3_bits | GIE);
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=SD24_VECTOR
__interrupt void SD24_ISR(void) {
#elif defined(__GNUC__)
void __attribute__ ((interrupt(SD24_VECTOR))) SD24_ISR(void)
#else
#error Compiler not supported!
#endif
switch(__even_in_range(SD24IV,SD24IV_SD24MEM3))
{
case SD24IV_NONE: break;
case SD24IV_SD24OVIFG: break;
case SD24IV_SD24MEM0: break;
case SD24IV_SD24MEM1: break;
case SD24IV_SD24MEM2: break;
case SD24IV_SD24MEM3:
// Save CH2 results (clears IFG)
Ch0results[index] = SD24_getResults(SD24_BASE, SD24_CONVERTER_0)>>2;
Ch1results[index] = SD24_getResults(SD24_BASE, SD24_CONVERTER_1)>>2;
Ch2results[index] = SD24_getResults(SD24_BASE, SD24_CONVERTER_2)>>2;
Ch3results[index] = SD24_getResults(SD24_BASE, SD24_CONVERTER_3)>>2;
index++;
break;
default: break;
}
if(index == Num_of_Results)
{
index = 0;
//When 4 conversion are done compute the mean of the four conversion
downLeftResultMean = (Ch0results[0] + Ch0results[1] + Ch0results[2] + Ch0results[3]); //downLeftResultMean
upLeftResultMean = (Ch1results[0])+(Ch1results[1])+(Ch1results[2])+(Ch1results[3]); //upLeftResultMean
upRightResultMean = (Ch2results[0])+(Ch2results[1])+(Ch2results[2])+(Ch2results[3]); //upRightResultMean
downRightResultMean = (Ch3results[0])+(Ch3results[1])+(Ch3results[2])+(Ch3results[3]); //downRightResultMean
//SD24CCTL3 &= ~SD24SC;
SD24CCTL3 &= ~SD24IE;
__bic_SR_register_on_exit(LPM0_bits); // Return to LPM3 after reti
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=WDT_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(WDT_VECTOR)))
#endif
void WDT_ISR(void)
{
SD24CCTL3 |= SD24SC | SD24IE;
__bis_SR_register_on_exit(LPM0_bits | GIE);
}