Problem with ADC using DMA in dspic33f

Thread Starter

Harnee15

Joined Sep 14, 2015
24
Hi everyone,

I'm a new programmer of dspic33f and facing issues with getting ADC working with DMA. I'm using dspic33fj128mc804 and need to read 8 analog readings using DMA. The problem is that I can see the values on putty but however the values are not always correct. For example: in case of just printing one readings I get the below output.

Can anyone please help me with this , please?

Below is my code and the screenshot of the output.

Thanks much in advance!

Code:
/*=======================================================================
Initialize ADC
========================================================================= */

void initadc(void)
{
AD1CON1bits.FORM   = 0;  // Data Output Format: Integer
AD1CON1bits.SSRC   = 7;  // Sample Clock Source: GP Timer starts conversion
AD1CON1bits.ASAM   = 1;  // ADC Sample Control: Sampling begins immediately after conversion
AD1CON1bits.AD12B  = 1;  // 12-bit ADC operation

AD1CON2bits.CSCNA = 1;  // Scan Input Selections for CH0+ during Sample A bit
AD1CON2bits.CHPS  = 0;  // Converts CH0

AD1CON3bits.ADRC = 0;  // ADC Clock is derived from Systems Clock
AD1CON3bits.ADCS = 65;  // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*64 = 1.6us (625Khz)
        // ADC Conversion Time for 10-bit Tc=12*Tab = 19.2us

AD1CON1bits.ADDMABM = 0;  // DMA buffers are built in scatter/gather mode
AD1CON2bits.SMPI    = (NUM_CHS2SCAN-1); // 8 ADC Channel is scanned
AD1CON4bits.DMABL   = 3; // Each buffer contains 8 words

//AD1CSSH/AD1CSSL: A/D Input Scan Selection Register
   
AD1CSSLbits.CSS0=1;   // Enable AN4 for channel scan
AD1CSSLbits.CSS1=1;   // Enable AN5 for channel scan
AD1CSSLbits.CSS2=1;  // Enable AN10 for channel scan
AD1CSSLbits.CSS3=1;  // Enable AN13 for channel scan
AD1CSSLbits.CSS4=1;
AD1CSSLbits.CSS5=1;
AD1CSSLbits.CSS6=1;
AD1CSSLbits.CSS7=1;
  
IFS0bits.AD1IF   = 0;  // Clear the A/D interrupt flag bit
IEC0bits.AD1IE   = 0;  // Do Not Enable A/D interrupt
AD1CON1bits.ADON = 1;  // Turn on the A/D converter

}


/*=======================================================================
Initialize DMA
========================================================================= */

void initDma0(void)
{
DMA0CONbits.AMODE = 2;   // Configure DMA for Peripheral indirect mode
DMA0CONbits.MODE  = 2;   // Configure DMA for Continuous Ping-Pong mode
DMA0PAD=(int)&ADC1BUF0;
DMA0CNT = (SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1;    
DMA0REQ = 13;     // Select ADC1 as DMA Request source

DMA0STA = __builtin_dmaoffset(&BufferA); 

IFS0bits.DMA0IF = 0;   //Clear the DMA interrupt flag bit
    IEC0bits.DMA0IE = 1;   //Set the DMA interrupt enable bit

DMA0CONbits.CHEN=1;    // Enable DMA

}

unsigned int DmaBuffer = 0;

/*=============================================================================
_DMA0Interrupt(): ISR name is chosen from the device linker script.
=============================================================================*/

void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
if(DmaBuffer == 0)
{
  ProcessADCSamples(&BufferA[1][1]);
ProcessADCSamples(&BufferA[2][1]);
ProcessADCSamples(&BufferA[3][1]);
 ProcessADCSamples(&BufferA[4][1]);
ProcessADCSamples(&BufferA[5][1]);
ProcessADCSamples(&BufferA[6][1]);
ProcessADCSamples(&BufferA[7][1]);
ProcessADCSamples(&BufferA[8][1]);
}
DmaBuffer ^= 1;
IFS0bits.DMA0IF = 0;  // Clear the DMA0 Interrupt Flag
}

void ProcessADCSamples(int * AdcBuffer)
{
adResults[adChannelCounter]=*AdcBuffer;
adChannelCounter++;
adChannelCounter&=0x7;      //Allows 0-7

AD1CHS0=adChannelMap[adChannelCounter]; //set the channel

 if (adChannelCounter==0)  //rolled over, so we have 8 samples
 {
shouldWriteResults = 1;  //set flag.
}
}
Output

Capture.PNG
 
Top