Prev: Looking for 2nd hand electronic tools
Next: A tool that suggests optimized logic for a piece of code/module/function
From: bharath reddy sareddy on 12 Jan 2010 04:08 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 operation AD1CON2bits.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.4us AD1CON1bits.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 1 DAC1STATbits.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+1 DAC1CONbits.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 bit T3CONbits.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 mode DMA0PAD = (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 |