Frustrating problem with dsPic30F3012 ADC...

Started by demolitron May 17, 2009
Hello,

I just got my board built for my new dsPic project and I've run into a very puzzling problem with the ADC. If you all would be kind enough to take a look for me. I hope this isn't something simple and stupid I've missed...

First, my environment:

dsPic30F3012 @ 3.3V
MPLAB 8.30
MPLAB C30 student edition version 3.12 compiler
PICKIT 2 Debugger (DE Version = 1.40.3)
USART level shifter = MAX3232
Terminal Software= Standard Windows HyperTerm

I have six analog inputs (AN0-AN3,AN6,AN7), three from a 3-Axis Accelerometer (AN1-AN3) and the rest from a 3-Axis Magneto Resistive sensor array. I sample all six 16 times then shift the result down 4 bits to get an average. I've included my source code below.

The Problem:
At first everything runs great, no problems. But after a random time interval the MCU seems to lock up. I pause execution from the debugger I can see it is looping at the "while(!ADCON1bits.DONE);" statement. ADCON1bits.DONE is indeed clear. ADCON1bits.SAMP is set.

Further inspection of the ADCON1 register bits reveals that SSRC bit 2 (ADCON1<7>) has been cleared. So now it is set to a reserved value, not the desired internal counter triggered mode.

I've looked and looked but can not find anything, anywhere that could cause this change. Anyone, could you give me a hand?

Thanks!!!

_--------
-------
-----------
#include

int main(void);
void ADC_Init(void);
void UART_Init(void);
void putch(unsigned char dat);
void prints(const char * dat);
void print_int(unsigned int val, unsigned char places);

unsigned int Az, Ax, Ay, Hz, Hx, Hy,t,i;

int main(void)
{

ADC_Init();
UART_Init();

TRISC0101111111111111;

do
{
Az=0;
Ax=0;
Ay=0;
Hz=0;
Hx=0;
Hy=0;

ADCHS = 0x0001;

for(i=0;i<16;i++)
{

ADCON1bits.DONE=0;
ADCON1bits.SAMP=1;
while(!ADCON1bits.DONE);
ADCHS = 0x0002;
Az+CBUF0;

ADCON1bits.DONE=0;
ADCON1bits.SAMP=1;
while(!ADCON1bits.DONE);
ADCHS = 0x0003;
Ay+CBUF0;

ADCON1bits.DONE=0;
ADCON1bits.SAMP=1;
while(!ADCON1bits.DONE);
ADCHS = 0x0000;
Ax+CBUF0;

ADCON1bits.DONE=0;
ADCON1bits.SAMP=1;
while(!ADCON1bits.DONE);
ADCHS = 0x0006;
Hz+CBUF0;

ADCON1bits.DONE=0;
ADCON1bits.SAMP=1;
while(!ADCON1bits.DONE);
ADCHS = 0x0007;
Hx+CBUF0;

ADCON1bits.DONE=0;
ADCON1bits.SAMP=1;
while(!ADCON1bits.DONE);
ADCHS = 0x0001;
Hy+CBUF0;
}
Az>>=4;
Ay>>=4;
Ax>>=4;
Hz>>=4;
Hy>>=4;
Hx>>=4;

prints("Ax:");
print_int (Ax,5);
prints(" Ay:");
print_int (Ay,5);
prints(" Az:");
print_int (Az,5);

prints(" Hx:");
print_int (Hx,5);
prints(" Hy:");
print_int (Hy,5);
prints(" Hz:");
print_int (Hz,5);

prints(" \r");

} while(1);
return(0);
}

void ADC_Init(void)
{

ADCON1bits.FORM = 0;
ADCON1bits.SSRC = 7; //Auto Convert once Sample is Completed
ADCON1bits.ASAM = 0; //Sample only when SAMP bit is set manually

ADCON2bits.SMPI = 0;

ADCON3bits.SAMC = 1;
ADCON3bits.ADRC = 1;

ADCSSL = 0x0000;

ADPCFG = 0b1111111100110000;

TRISB=0xFFFF;

IFS0bits.ADIF = 0;
IEC0bits.ADIE = 0;
ADCON1bits.ADON = 1;

}

void UART_Init(void)
{
U1BRG; //19200bps
U1MODEbits.ALTIO=1; //Use Alternate Pins
U1MODEbits.UARTEN=1;
U1STAbits.UTXEN=1;
}

void prints(const char * dat)
{
while(*dat)
{
putch(*dat);
dat++;
}
}

void putch(unsigned char dat)
{
while(!U1STAbits.TRMT);
U1TXREG;
}

void print_int(unsigned int val, unsigned char places)
{
unsigned int fp_temp;
int fp_i;
char buffer[5];

for (fp_i=0;fp_i {
fp_temp=val/10;
buffer[fp_i]=('0'+(val-(fp_temp*10)));
val=fp_temp;
}

for(fp_i=places-1;!(fp_i==-1);fp_i--)
{
putch(buffer[fp_i]);
}

}