1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

regarding DAC in dsPIC33FJ128GP802

Discussion in 'Embedded' started by bharath reddy sareddy, Jan 12, 2010.

  1. 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
    // Clock Switching is enabled and
    Fail Safe Clock Monitor is disabled
    // OSC2 Pin Function: OSC2 is
    Clock Output
    // Primary Oscillator Mode:

    _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

    // Clock switch to incorporate PLL
    __builtin_write_OSCCONH(0x01); // Initiate Clock Switch
    // 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
    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
    for(i = 0; i < NUMSAMP; i++)
    while(DAC1STATbits.REMPTY != 1);// Wait for D/A conversion
    if(DmaBuffer == 0)
    DAC1RDAT = BufferA; // Load the DAC buffer with
    DAC1RDAT = BufferB; // Load the DAC buffer with
    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
    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
    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
    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
    ACLKCONbits.APSTSCLR = 7; // FRC divide by 1

    DAC1STATbits.ROEN = 1; // Right Channel DAC Output

    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
    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
    DMA0CNT = (NUMSAMP-1); // DMA Transfer Count is

    DMA0REQ = 13; // ADC interrupt selected for DMA
    channel IRQ

    DMA0STA = __builtin_dmaoffset(BufferA); // DMA RAM Start Address
    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

    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
    bharath reddy sareddy, Jan 12, 2010
    1. Advertisements

  2. bharath reddy sareddy


    Sep 26, 2010
    Likes Received:
    Same here

    I have the same problem (exact same chip). I have a working ADC, but the DAC just outputs the default value (1.65V).
    In the debugger, the void __attribute__((interrupt, no_auto_psv)) _DAC1RInterrupt(void) function is only called once/a few times and is then never called any more.
    I use the sample code from "Section 33. Audio Digital-to-Analog Converter (DAC) - dsPIC33F FRM" - "33.6 AUDIO DAC OPERATION WITHOUT DMA". I am now going to try if the code with DMA works.

    I see in your code that you set your DAC1RDAT in main instead of the interrupt function. You also feed the ADC buffer directly to the DAC, maybe you should use an intermediate buffer.

    Have you found a solution?
    redef, Sep 26, 2010
    1. Advertisements

  3. bharath reddy sareddy


    Feb 28, 2016
    Likes Received:
    I just had the same probleme. My mistake was that I forgot to connect AVdd and AVss. Now it's working fine.
    Maxime, Feb 28, 2016
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.