hi frds
im using dsPIC33FJ128GP802 for my application im trying with ADC-DAC loop back as intial step. my ADC is working finely but i have a strange problem with DAC.......... intially data register(DAC1RDAT) is loading with default value and then always it is going to zero.............. i have tried with the example given by microchip also.....it is also giving the same problem i m not geting where is the mistake is there any thing wrong with device or code here is the code i have taken
// Internal FRC Oscillator _FOSCSEL(FNOSC_FRC); // FRC Oscillator _FOSC(FCKSM_CSECMD & OSCIOFNC_ON & POSCMD_NONE); // Clock Switching is enabled and Fail Safe Clock Monitor is disabled // OSC2 Pin Function: OSC2 is Clock Output // Primary Oscillator Mode: Disabled
_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/ disabled by user software // (LPRC can be disabled by clearing SWDTEN bit in RCON register
int main (void) { // Configure Oscillator to operate the device at 40MIPS // Fosc= Fin*M/(N1*N2), Fcy=Fosc/2 // Fosc= 7.37M*43/(2*2)=79.22Mhz for ~40MIPS input clock PLLFBD=41; // M=43 CLKDIVbits.PLLPOST=0; // N1=2 CLKDIVbits.PLLPRE=0; // N2=2 OSCTUN=0; // Tune FRC oscillator, if FRC is used
// Disable Watch Dog Timer RCONbits.SWDTEN=0;
// Clock switch to incorporate PLL __builtin_write_OSCCONH(0x01); // Initiate Clock Switch to // FRC with PLL (NOSC=0b001) __builtin_write_OSCCONL(0x01); // Start clock switching while (OSCCONbits.COSC != 0b001); // Wait for Clock switch to occur
// Wait for PLL to lock while(OSCCONbits.LOCK!=1) {};
initAdc(); // Initialize the A/D converter to convert Channel 4 initDac(); // Initialize the D/A converter initDma0(); // Initialize the DMA controller to buffer ADC data in conversion order initTmr3(); // Initialize the Timer to generate sampling event for ADC
extern fractional BufferA[NUMSAMP]; // Ping pong buffer A extern fractional BufferB[NUMSAMP]; // Ping pong buffer B extern unsigned int DmaBuffer; // DMA flag extern int flag; // Flag int i;
while (1) // Loop Endlessly - Execution is interrupt driven { if(flag) { for(i = 0; i < NUMSAMP; i++) { while(DAC1STATbits.REMPTY != 1);// Wait for D/A conversion if(DmaBuffer == 0) DAC1RDAT = BufferA[i]; // Load the DAC buffer with data else DAC1RDAT = BufferB[i]; // Load the DAC buffer with data } flag = 0; } }
return 0;
}#include "p33fxxxx.h" #include "dsp.h" #include "..\h\adcdacDrv.h"
fractional BufferA[NUMSAMP] __attribute__((space(dma))); // Ping- pong buffer A fractional BufferB[NUMSAMP] __attribute__((space(dma))); // Ping- pong buffer B
/ *============================================================================= initAdc() is used to configure A/D to convert channel 4 on Timer event. It generates event to DMA on every sample/convert sequence. =============================================================================*/ void initAdc(void) { AD1CON1bits.FORM = 3; // Data Output Format: Signed Fraction (Q15 format) AD1CON1bits.SSRC = 2; // Sample Clock Source: GP Timer starts conversion AD1CON1bits.ASAM = 1; // ADC Sample Control: Sampling begins immediately after conversion AD1CON1bits.AD12B = 1; // 12-bit ADC operationAD1CON2bits.CHPS = 0; // Converts CH0
AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock AD1CON3bits.ADCS = 3; // ADC Conversion Clock Tad=Tcy*(ADCS
+1)= (1/40M)*4 = 100ns // ADC Conversion Time for 12-bit Tc=14*Tad = 1.4usAD1CON1bits.ADDMABM = 1; // DMA buffers are built in conversion order mode AD1CON2bits.SMPI = 0; // SMPI must be 0
//AD1CHS0: A/D Input Select Register AD1CHS0bits.CH0SA = 4; // MUXA +ve input selection (AN4) for CH0 AD1CHS0bits.CH0NA = 0; // MUXA -ve input selection (Vref-) for CH0
//AD1PCFGH/AD1PCFGL: Port Configuration Register AD1PCFGL=0xFFFF; AD1PCFGLbits.PCFG4 = 0; // AN4 as Analog Input
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 }
/ *============================================================================= initDac() is used to configure D/A. =============================================================================*/ void initDac(void) { /* Initiate DAC Clock */ ACLKCONbits.SELACLK = 0; // FRC w/ Pll as Clock Source ACLKCONbits.AOSCMD = 0; // Auxiliary Oscillator Disabled ACLKCONbits.ASRCSEL = 0; // Auxiliary Oscillator is the Clock Source ACLKCONbits.APSTSCLR = 7; // FRC divide by 1DAC1STATbits.ROEN = 1; // Right Channel DAC Output Enabled
DAC1DFLT = 0x8000; // DAC Default value is the midpoint
// 103.16KHz // 8.038KHz //
44.211KHz // 25KHz DAC1CONbits.DACFDIV = 5; //76; // 13; // 23; // // Divide High Speed Clock by DACFDIV+1DAC1CONbits.FORM = 1; // Data Format is signed integer DAC1CONbits.AMPON = 0; // Analog Output Amplifier is enabled during Sleep Mode/Stop-in Idle mode
DAC1CONbits.DACEN = 1; // DAC1 Module Enabled }
/ *======================================================================================= Timer 3 is setup to time-out every Ts secs. As a result, the module will stop sampling and trigger a conversion on every Timer3 time-out Ts. At that time, the conversion process starts and completes Tc=12*Tad periods later. When the conversion completes, the module starts sampling again. However, since Timer3 is already on and counting, about (Ts-Tc)us later, Timer3 will expire again and trigger next conversion. =======================================================================================*/ void initTmr3() { TMR3 = 0x0000; // Clear TMR3 PR3 = SAMPPRD; // Load period value in PR3 IFS0bits.T3IF = 0; // Clear Timer 3 Interrupt Flag IEC0bits.T3IE = 0; // Clear Timer 3 interrupt enable bitT3CONbits.TON = 1; // Enable Timer 3 }
/ *============================================================================= DMA0 configuration Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM AMODE: Register indirect with post increment MODE: Continuous, Ping-Pong Mode IRQ: ADC Interrupt ADC stores results stored alternatively between BufferA[] and BufferB [] =============================================================================*/ void initDma0(void) { DMA0CONbits.AMODE = 0; // Configure DMA for Register indirect with post increment DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping- Pong modeDMA0PAD = (int)&ADC1BUF0; // Peripheral Address Register: ADC buffer DMA0CNT = (NUMSAMP-1); // DMA Transfer Count is (NUMSAMP-1)
DMA0REQ = 13; // ADC interrupt selected for DMA channel IRQ
DMA0STA = __builtin_dmaoffset(BufferA); // DMA RAM Start Address A DMA0STB = __builtin_dmaoffset(BufferB); // DMA RAM Start Address B
IFS0bits.DMA0IF = 0; // Clear the DMA interrupt flag bit IEC0bits.DMA0IE = 1; // Set the DMA interrupt enable bit
DMA0CONbits.CHEN = 1; // Enable DMA channel }
/ *============================================================================= _DMA0Interrupt(): ISR name is chosen from the device linker script. =============================================================================*/ unsigned int DmaBuffer = 0; int flag = 0;void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void) { DmaBuffer ^= 1; // Ping-pong buffer select flag flag = 1; // Ping-pong buffer full flag IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag }
/ *============================================================================= _DAC1RInterrupt(): ISR name is chosen from the device linker script. =============================================================================*/ void __attribute__((interrupt, no_auto_psv)) _DAC1RInterrupt(void) { IFS4bits.DAC1RIF = 0; // Clear Right Channel Interrupt Flag }if any body already worked on DAC of dsPIC33FJ128GP802
plz help me...................my project has stucked at this point.............its very urgent for me
thnks to all in advance