EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

regarding DAC in dsPIC33FJ128GP802

Started by bharath reddy sareddy January 12, 2010
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

The 2024 Embedded Online Conference