How to configure ADC sampling rate?


Closed Thread
Results 1 to 3 of 3
  1. #1
    Join Date
    Jan 2013
    Posts
    2

    Default How to configure ADC sampling rate?

    Hi!

    I am using dsPIC Starter Kit which has a dsPIC33fj256gp506. I am trying to modify the ADC sampling rate using the example from Microchip.

    Here is the code:

    Code:
    #ifndef __ADCCHANNELDRV_H__ 
    #define __ADCCHANNELDRV_H__ 
     #define ADC_CHANNEL_FCY   40000000
    #define ADC_FSAMP    8000 /* Sampling Frequency */ 
    #define ADC_BUFFER_SIZE   128    /* This is the size of each buffer */ 
    #define ADC_CHANNEL_DMA_BUFSIZE (ADC_BUFFER_SIZE*2)  
       
     #include "..\h\p33FJ256GP506.h" 
     typedef struct sADCChannelHandle { 
     int * buffer1; 
     int * buffer2; 
     volatile int bufferIndicator; 
     volatile int isReadBusy; 
      
    }ADCChannelHandle; 
     void ADCChannelInit (ADCChannelHandle * pHandle,int * pBufferInDMA); 
    void ADCChannelStart (ADCChannelHandle * pHandle); 
    void ADCChannelRead (ADCChannelHandle * pHandle,int *buffer,int size); 
    int ADCChannelIsBusy (ADCChannelHandle * pHandle); 
    void ADCChannelStop (ADCChannelHandle * pHandle);
    #define ADCON1VAL   0x0744    /* 12 bit ADC with signed fractional format 
                                                * Triggered by Timer 3 and auto start 
                                                         * sampling after conversion complete. */ 
    #define ADCON2VAL   0x0000      /* AVdd and AVss voltage reference,  
                                                          * use channel 0 with no scan */
    #define ADCON3VAL  0x0010      /* Tad is 16 Tcy     */     
    #define ADCHSVAL  0x0000  /* AN0 input on channel 0  */    
    #define ADPCFGVAL  0xFFFE  /* AN0 input is Analog   */ 
    #define ADCSSLVAL  0x0000   /* No channel scanning   */ 
     #endif 
     
      
     #include "..\h\ADCChannelDrv.h" 
     static ADCChannelHandle * thisADCChannel; 
     void ADCChannelInit (ADCChannelHandle * pHandle,int * pBufferInDMA) 
    { 
     /* This function will intialize the DMA  */ 
     /* DMA0 is used to read from the ADC  */ 
      
      thisADCChannel = pHandle; 
     pHandle->buffer1  = pBufferInDMA; /* Assign the ping pong buffers for the ADC DMA*/ 
     pHandle->buffer2  = (int *)((int)pBufferInDMA + ADC_BUFFER_SIZE); 
       
     DMA0CONbits.SIZE  = 0;  /* Word transfers       */ 
     DMA0CONbits.DIR  = 0;  /* From ADC1BUF to DMA     */ 
     DMA0CONbits.HALF  = 0;  /* Interrupt when all the data has been moved */ 
     DMA0CONbits.NULLW  = 0;  /* No NULL writes - Normal Operation   */ 
     DMA0CONbits.AMODE  = 0;  /* Register Indirect with post-increment mode */ 
     DMA0CONbits.MODE  = 2;  /* Continuous  ping pong mode enabled  */ 
      
     DMA0REQbits.FORCE  = 0;  /* Automatic transfer    */ 
     DMA0REQbits.IRQSEL = 0xD; /* ADC conversion complete   */ 
      
     DMA0STA = (int)(pHandle->buffer1) - (int)&_DMA_BASE; 
     DMA0STB  = (int)(pHandle->buffer2) - (int)&_DMA_BASE; 
      
      DMA0PAD = (int )&ADC1BUF0; 
     DMA0CNT = ADC_BUFFER_SIZE - 1; 
      AD1CON1  = ADCON1VAL;    /* Load the ADC registers with  value  */                             
     AD1CON2  = ADCON2VAL;    /* specified in 12bitADCDriver.h */  
     AD1CON3  = ADCON3VAL;                               
     AD1CHS0  = ADCHSVAL;                               
     AD1PCFGLbits.PCFG0 = 0; 
     AD1CSSL  = ADCSSLVAL;
    TMR3   = 0; 
     PR3  = (ADC_CHANNEL_FCY/ADC_FSAMP) - 1; 
     } 
       
     void ADCChannelStart (ADCChannelHandle * pHandle) 
    { 
     pHandle->bufferIndicator  = 0; 
     pHandle->isReadBusy   = 1; 
     _DMA0IF = 0; 
     _DMA0IE = 1; 
     DMA0CONbits.CHEN = 1;  /* Enable the DMA Channel */ 
     AD1CON1bits.ADON = 1;  /* Enable ADC module  */ 
     T3CONbits.TON   = 1;  /* Enable Timer 3        */ 
     } 
     void ADCChannelStop(ADCChannelHandle * pHandle) 
    { 
     _DMA0IE = 0;    /* Disable the DMA interrupt */ 
     DMA0CONbits.CHEN = 0;  /* Disable the DMA Channel */ 
     AD1CON1bits.ADON = 0;  /* Disable ADC module  */ 
     T3CONbits.TON   = 0;  /* Disable Timer 3        */ 
    }  
     void ADCChannelRead (ADCChannelHandle * pHandle,int *data,int size) 
    { 
     int *source; 
     int  i; 
      
     /* if the buffer indicator bit is 1, then use buffer 1 else use buffer2 */ 
     /* Since the DMA ping pongs between these buffer, you must know */ 
     /* which one to read. The bufferIndicators keep track of this  */ 
      
     source = (pHandle->bufferIndicator) ? pHandle->buffer1 : pHandle->buffer2; 
     if (size > ADC_BUFFER_SIZE) size = ADC_BUFFER_SIZE; 
       
     for(i = 0;i < size;i++) 
     { 
      data[i] = source[i]; 
     } 
     __asm__ volatile("disi #0x4"); /* disable interrupts */ 
     pHandle->isReadBusy = 1; 
     __asm__ volatile("disi #0x0"); /* enable interrupts */ 
     } 
     int ADCChannelIsBusy (ADCChannelHandle * pHandle) 
    { 
     return(pHandle->isReadBusy); 
    } 
     void __attribute__((__interrupt__,no_auto_psv)) _DMA0Interrupt(void) 
    { 
      
     _DMA0IF = 0; 
     thisADCChannel->bufferIndicator   ^= 1;  /* Flip the indicator bit  */ 
     thisADCChannel->isReadBusy  = 0;   /* New frame is available */ 
    }
    I want to set it to 60kHz. I set ADC_FSAMP = 60000, and calculate ADCS.

    Tcy = 25ns (@40MHz)
    Tc = 1/60000 = 16.66us = 16666ns (aprox.)
    Tad = Tc/14 = 1190ns (aprox.)
    ADC Conversion Clock: Tad=Tcy*(ADCS+1) => ADCS = (Tad/Tcy) - 1 = 46,61 = 47 (aprox.).
    I set ADCS = 47, so I write:

    Code:
    #define ADCON3VAL 0x002F
    To test if the ADC is working correctly, I generate a 10kHz signal for the board using my PC sound card (using Visual Analyser 2011). But the ADC won't finish sampling (I use a LED to signal when 128 samples have been acquired - when finished, the LED switches off). Also, if I generate a DC signal, the ADC won't finish sampling. More interesting is the fact that when I generate a 1kHz signal, the ADC works fine!! I used debug to view the samples, exported the values in a file and plotted them in Matlab.Please help in solving this problem. I really need to get this ADC running for a project I am working on.

  2. #2
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: How to configure ADC sampling rate?

    Maybe you should try a C forum. Here we do Basic only.

    Ioannis

  3. #3
    Join Date
    Jan 2013
    Posts
    2


    Did you find this post helpful? Yes | No

    Default Re: How to configure ADC sampling rate?

    OK. I will try another forum. Thanks!

Similar Threads

  1. Picbasic and ADC set_up
    By iw2fvo in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 13th January 2013, 09:26
  2. Help with multiple ADC inputs
    By wdmagic in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 4th January 2013, 00:27
  3. CONFIGURE & OSCCON & meProg configure
    By SUNFLOWER in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 19th February 2011, 21:25
  4. Replies: 1
    Last Post: - 19th February 2011, 18:35
  5. Sampling rate - PIC16F877
    By Tomas in forum mel PIC BASIC Pro
    Replies: 26
    Last Post: - 29th January 2011, 10:00

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts