Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Simultaneous Sampling using dsPic33fj without DMA

Status
Not open for further replies.

heryrg

Junior Member level 1
Joined
Nov 20, 2009
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,416
Hello friends. I have a question for you all. I'm working on a little project where i need to keep track of 4 analog inputs. I'm using dsPic33fj to simultaneously sample these 4 inputs. See the image bellow for illustration of what i want to do. My question is: can i manually save each conversion after it is done without using DMA? So after step3 save convert1 then after step4 save convert2 and so on.

Ultimately i do not want to use DMA but will if i really have to. I would like to use ADC1 Interrupt after each conversion but even if i specify 1 conversion between interrupts, the interrupt does not get triggered after each conversion. Below is the ADC initialization, ADC interrupt, and DMA initialization.

I know i probably left some details out, so please be kind to ask me questions or let me know if you need more info. Also, please if you could please let me know if i setup my DMA buffers correct.

ADC Initialization:
Code:
void initAdc1(void)
{

AD1CON1bits.ADON = 0;
AD1CON1bits.AD12B = 0; // Select 10-bit mode 1=12bit
AD1CON2bits.CHPS = 3; // Select 4-channel mode
AD1CON1bits.SIMSAM = 1; // Enable Simultaneous Sampling
AD1CON1bits.ADDMABM = 1; // DMA buffer written in order of conversion
AD1CON2bits.ALTS = 1; // Enable Alternate Input Selection
AD1CON2bits.SMPI = 1; // Select 1 conversion between interrupt
AD1CON1bits.ASAM = 1; // Enable Automatic Sampling 0=SAMP must be set before sampling
AD1CON1bits.SSRC = 2; // Timer3 generates SOC trigger
AD1CON2bits.CSCNA = 0; // No input scan

//	AD1CON3bits.ADRC=0;			// ADC Clock is derived from Systems Clock
//	AD1CON3bits.ADCS = 63;		// ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*64 = 1.6us (625Khz)

// Initialize MUXA Input Selection
AD1CHS0bits.CH0SA = 8; // Select AN8 for CH0 +ve input
AD1CHS0bits.CH0NA = 0; // Select VREF- for CH0 -ve input
AD1CHS123bits.CH123SA = 0; // Select CH1 +ve = AN0, CH2 +ve = AN1, CH3 +ve = AN2
AD1CHS123bits.CH123NA = 0; // Select VREF- for CH1/CH2/CH3 -ve inputs

// Initialize MUXB Input Selection
AD1CHS0bits.CH0SB = 11; // Select AN11 for CH0 +ve input
AD1CHS0bits.CH0NB = 0; // Select VREF- for CH0 -ve input
AD1CHS123bits.CH123SB = 1; // Select CH1 +ve = AN3, CH2 +ve = AN4, CH3 +ve = AN5

IPC3bits.AD1IP = 7;			// Set Priority to highest level 7 
IFS0bits.AD1IF = 0;			// Clear the A/D interrupt flag bit
IEC0bits.AD1IE = 1;			// Enable A/D interrupt 
AD1CON1bits.ADON = 1;


}

DMA Initialization:
Code:
#define  MAX_CHNUM	 			13		// Highest Analog input number in Channel Scan
#define  SAMP_BUFF_SIZE	 		8		// Size of the input buffer per analog input
#define  NUM_CHS2SCAN			4		// Number of channels enabled for channel scan


// Number of locations for ADC buffer = 14 (AN0 to AN13) x 8 = 112 words
// Align the buffer to 128 words or 256 bytes. This is needed for peripheral indirect mode
int  BufferA[MAX_CHNUM+1][SAMP_BUFF_SIZE] __attribute__((space(dma),aligned(256)));
int  BufferB[MAX_CHNUM+1][SAMP_BUFF_SIZE] __attribute__((space(dma),aligned(256)));

void initDma0(void)
{
	DMA0CONbits.AMODE = 2;			// Configure DMA for Peripheral indirect mode
	DMA0CONbits.MODE  = 2;			// Configure DMA for Continuous Ping-Pong mode

	DMA0CNT = (SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1;					
	DMA0REQ = 13;					// Select ADC1 as DMA Request source	
	
	DMA0STA = __builtin_dmaoffset(BufferA);		
	DMA0STB = __builtin_dmaoffset(BufferB);

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


}

ADC1 Interrupt:
Code:
void __attribute__((interrupt, no_auto_psv)) _ADC1Interrupt(void)
{
		
		if (y < 127)
		{
  		array[y] = ADC1BUF0; //  get ADC value 
		LATE = array[y];       // Display the data
		y++;
		}
		else y=0;
		
		IFS0bits.AD1IF = 0;			// Clear the A/D interrupt flag bit
	
}
 

Problem solved. Timer triggering ADC1 was too long. Such a simple solution, go figure. DMA bufferA & bufferB still do not save the data for some odd reason.
 

heryrg is your code working?
I wanna doing same thing using pic24hj128gp306 to read multiple channels simultaneously without using DMA.Can you give me some help regarding this?

Thanks
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top