Problem with ADC using DMA in dspic33f

Discussion in 'Embedded Systems and Microcontrollers' started by Harnee15, Apr 4, 2016.

  1. Harnee15

    Thread Starter New Member

    Sep 14, 2015
    24
    0
    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 (Text):
    1. /*=======================================================================
    2. Initialize ADC
    3. ========================================================================= */
    4.  
    5. void initadc(void)
    6. {
    7. AD1CON1bits.FORM   = 0;  // Data Output Format: Integer
    8. AD1CON1bits.SSRC   = 7;  // Sample Clock Source: GP Timer starts conversion
    9. AD1CON1bits.ASAM   = 1;  // ADC Sample Control: Sampling begins immediately after conversion
    10. AD1CON1bits.AD12B  = 1;  // 12-bit ADC operation
    11.  
    12. AD1CON2bits.CSCNA = 1;  // Scan Input Selections for CH0+ during Sample A bit
    13. AD1CON2bits.CHPS  = 0;  // Converts CH0
    14.  
    15. AD1CON3bits.ADRC = 0;  // ADC Clock is derived from Systems Clock
    16. AD1CON3bits.ADCS = 65;  // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*64 = 1.6us (625Khz)
    17.         // ADC Conversion Time for 10-bit Tc=12*Tab = 19.2us
    18.  
    19. AD1CON1bits.ADDMABM = 0;  // DMA buffers are built in scatter/gather mode
    20. AD1CON2bits.SMPI    = (NUM_CHS2SCAN-1); // 8 ADC Channel is scanned
    21. AD1CON4bits.DMABL   = 3; // Each buffer contains 8 words
    22.  
    23. //AD1CSSH/AD1CSSL: A/D Input Scan Selection Register
    24.    
    25. AD1CSSLbits.CSS0=1;   // Enable AN4 for channel scan
    26. AD1CSSLbits.CSS1=1;   // Enable AN5 for channel scan
    27. AD1CSSLbits.CSS2=1;  // Enable AN10 for channel scan
    28. AD1CSSLbits.CSS3=1;  // Enable AN13 for channel scan
    29. AD1CSSLbits.CSS4=1;
    30. AD1CSSLbits.CSS5=1;
    31. AD1CSSLbits.CSS6=1;
    32. AD1CSSLbits.CSS7=1;
    33.  
    34. IFS0bits.AD1IF   = 0;  // Clear the A/D interrupt flag bit
    35. IEC0bits.AD1IE   = 0;  // Do Not Enable A/D interrupt
    36. AD1CON1bits.ADON = 1;  // Turn on the A/D converter
    37.  
    38. }
    39.  
    40.  
    41. /*=======================================================================
    42. Initialize DMA
    43. ========================================================================= */
    44.  
    45. void initDma0(void)
    46. {
    47. DMA0CONbits.AMODE = 2;   // Configure DMA for Peripheral indirect mode
    48. DMA0CONbits.MODE  = 2;   // Configure DMA for Continuous Ping-Pong mode
    49. DMA0PAD=(int)&ADC1BUF0;
    50. DMA0CNT = (SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1;    
    51. DMA0REQ = 13;     // Select ADC1 as DMA Request source
    52.  
    53. DMA0STA = __builtin_dmaoffset(&BufferA);
    54.  
    55. IFS0bits.DMA0IF = 0;   //Clear the DMA interrupt flag bit
    56.     IEC0bits.DMA0IE = 1;   //Set the DMA interrupt enable bit
    57.  
    58. DMA0CONbits.CHEN=1;    // Enable DMA
    59.  
    60. }
    61.  
    62. unsigned int DmaBuffer = 0;
    63.  
    64. /*=============================================================================
    65. _DMA0Interrupt(): ISR name is chosen from the device linker script.
    66. =============================================================================*/
    67.  
    68. void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
    69. {
    70. if(DmaBuffer == 0)
    71. {
    72.   ProcessADCSamples(&BufferA[1][1]);
    73. ProcessADCSamples(&BufferA[2][1]);
    74. ProcessADCSamples(&BufferA[3][1]);
    75.  ProcessADCSamples(&BufferA[4][1]);
    76. ProcessADCSamples(&BufferA[5][1]);
    77. ProcessADCSamples(&BufferA[6][1]);
    78. ProcessADCSamples(&BufferA[7][1]);
    79. ProcessADCSamples(&BufferA[8][1]);
    80. }
    81. DmaBuffer ^= 1;
    82. IFS0bits.DMA0IF = 0;  // Clear the DMA0 Interrupt Flag
    83. }
    84.  
    85. void ProcessADCSamples(int * AdcBuffer)
    86. {
    87. adResults[adChannelCounter]=*AdcBuffer;
    88. adChannelCounter++;
    89. adChannelCounter&=0x7;      //Allows 0-7
    90.  
    91. AD1CHS0=adChannelMap[adChannelCounter]; //set the channel
    92.  
    93.  if (adChannelCounter==0)  //rolled over, so we have 8 samples
    94.  {
    95. shouldWriteResults = 1;  //set flag.
    96. }
    97. }
    98.  
    Output

    Capture.PNG
     
Loading...