dxdx347
Newbie level 3
- Joined
- Jan 15, 2013
- Messages
- 3
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,312
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:
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:
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.
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
[B]#define ADC_FSAMP 8000 /* Sampling Frequency */ [/B]
#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
* [B]Triggered by Timer 3 [/B]and auto start
* sampling after conversion complete. */
#define ADCON2VAL 0x0000 /* AVdd and AVss voltage reference,
* use channel 0 with no scan */
#define ADCON3VAL 0x0010 [B] /* Tad is 16 Tcy */[/B]
#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;
[B]TMR3 = 0;
PR3 = (ADC_CHANNEL_FCY/ADC_FSAMP) - 1; [/B]
}
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:
[B]#define ADCON3VAL 0x002F[/B]
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.