CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

DAC80501 code support
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

DAC80501 code support
PostPosted: Fri Apr 05, 2024 11:16 am     Reply with quote

Hello,

I want to interface the PIC18F2520 with external 16 bit DAC (Example: DAC80501ZDQFR). Please can you support how to send data to the external DAC. Any code snippets to understand.

Internal Voltage reference: +2.5V

uC PIN SDO is connected to SDA
uC PIN SCK is connected to SCLK
uC PIN B1 is connected to SYNC/A0

Earlier I posted a topic for different DAC, but now would like to use this finally.

Thanks in advance.
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Fri Apr 05, 2024 12:25 pm     Reply with quote

Are you going to keep changing DACs then asking us for help with each one?
If you got the other one going, the same basic code should work for this one with changes to the command byte.

Starting out:
Read the datasheet...the interface is very similar to the earlier DAC.

Next:
For SPI you must tie SPI2C Low
Power on device
Set SYNC High

Then:
If needed, set/change bits in 8 bit command byte (0x08 for DAC output)
set SYNC Low
Output 8 bit command byte
Output 8 bit MSB SPI data
Output 8 bit LSB SPI data
Set SYNC High
Rinse and repeat...
_________________
Google and Forum Search are some of your best tools!!!!
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Mon May 20, 2024 2:25 am     Reply with quote

I tried the below code but it is not working. Any comments please.
Code:
#include "18F2520.h"
#fuses HS
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// Define SPI pins for DAC80501
#define DAC_CS    PIN_C2
#define DAC_SCLK PIN_C3
#define DAC_MOSI PIN_C5

// Function to initialize SPI for DAC80501
void init_spi(void) {
    setup_spi(SPI_MASTER | SPI_CLK_DIV_16 | SPI_H_TO_L | SPI_XMIT_L_TO_H);
    output_high(DAC_CS); // Deselect the DAC
}

// Function to write data to the DAC80501
void write_dac80501(unsigned int16 value) {
    unsigned int8 high_byte, low_byte;

    // Split the 16-bit value into two 8-bit values
    high_byte = (value >> 8) & 0xFF;
    low_byte = value & 0xFF;

    // Send the data to the DAC80501 over SPI
    output_low(DAC_CS); // Select the DAC
    spi_write(high_byte); // Send the high byte
    spi_write(low_byte); // Send the low byte
    output_high(DAC_CS); // Deselect the DAC
}

void main() {
    unsigned int16 dac_value = 0x8000; // Example value to set DAC to mid-scale

    // Initialize SPI
    init_spi();

    // Main loop
    while(TRUE) {
        // Write the example value to the DAC
        write_dac80501(dac_value);

        // Delay for demonstration purposes
        delay_ms(1000);
    }
}
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon May 20, 2024 5:24 am     Reply with quote

You're not sending the necessary 'command byte' as previous poster posted !!!
Curious , I downloaded the datasheet and it does say that you need to send 24 bits ( cmd,hsdb,lsdb) to the chip.
There's also a LOT of critical hardware design (PCB layout,opamp,parts,etc.) necessary to get accurate, repeatable 16 bit data.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Mon May 20, 2024 9:37 am     Reply with quote

Lets give a hint:
Code:

#define DACREG 0x80 //command byte to select the data register
// Function to write data to the DAC80501
void write_dac80501(unsigned int16 value)

    // Send the data to the DAC80501 over SPI
    output_low(DAC_CS); // Select the DAC
    spi_write(DACREG);
    spi_write(make8(value,1)); // Send the high byte
    spi_write(make8(value,0)); // Send the low byte
    output_high(DAC_CS); // Deselect the DAC
}


This should write the value to the data register. However you will
probably have to program the configurations first. Turn on the reference
and the DAC itself (two bits in the CONFIG register), and also program
the gain of the reference and the DAC itself (GAIN register).
Also I have not checked that the mode you are setting up in the
setup, is what this DAC requires. There also may be a problem with your
use of spi_write for the last byte. By default this command returns as soon
as the byte is loaded, it does not wait for the byte to actually be sent. So
as shown the CS (SYNC) signal may be raised too soon. It must not be
raised till the byte has finished transferring.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Mon May 20, 2024 9:38 am     Reply with quote

Lets give a hint:
Code:

#define DACREG 0x80 //command byte to select the data register
// Function to write data to the DAC80501
void write_dac80501(unsigned int16 value)

    // Send the data to the DAC80501 over SPI
    output_low(DAC_CS); // Select the DAC
    spi_write(DACREG); //select to write to the data register
    spi_write(make8(value,1)); // Send the high byte
    spi_write(make8(value,0)); // Send the low byte
    output_high(DAC_CS); // Deselect the DAC
}


This should write the value to the data register. However you will
probably have to program the configurations first. Turn on the reference
and the DAC itself (two bits in the CONFIG register), and also program
the gain of the reference and the DAC itself (GAIN register).
Also I have not checked that the mode you are setting up in the
setup, is what this DAC requires. There also may be a problem with your
use of spi_write for the last byte. By default this command returns as soon
as the byte is loaded, it does not wait for the byte to actually be sent. So
as shown the CS (SYNC) signal may be raised too soon. It must not be
raised till the byte has finished transferring.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Wed May 22, 2024 11:03 pm     Reply with quote

Thanks Ttelmah. It's really helpful Smile
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Thu Jun 20, 2024 11:24 am     Reply with quote

I tried the below code. Measured DAC output is +5V. I used internal reference 2.5V. Why the output is +5V? What should I modify to get the output of 2.5V at 65535.
Code:
#include "18F2520.h"
#fuses HS
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// Define SPI pins for DAC80501
#define DAC_CS   PIN_C2
#define DAC_SCLK PIN_C3
#define DAC_MOSI PIN_C5

#define DACREG 0x08 //command byte to select the data register

// Function to initialize SPI for DAC80501
void init_spi(void) {
   setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_64);
   output_high(DAC_CS);  // Deselect DAC
}

// Function to write data to the DAC80501
void write_dac80501(unsigned int16 value)
{
    // Send the data to the DAC80501 over SPI
    output_low(DAC_CS); // Select the DAC
    spi_write(DACREG);
    spi_write(make8(value,1)); // Send the high byte
    spi_write(make8(value,0)); // Send the l     ow byte
    output_high(DAC_CS); // Deselect the DAC
}

void main() {
    unsigned int16 dac_value;
   
   // Initialize SPI
    init_spi();
   
   // Send the data to the DAC80501 over SPI
   value1 = 0x000A;   // Soft reset
    output_low(DAC_CS); // Select the DAC
    spi_write(0x05);   // TRIGGER Register
    spi_write(make8(value1,1)); // Send the high byte
    spi_write(make8(value1,0)); // Send the low byte
    output_high(DAC_CS); // Deselect the DAC

    // Send the data to the DAC80501 over SPI
   value1 = 0x0100;   // REF-DIV divided by 2; Gain set to 1
    output_low(DAC_CS); // Select the DAC
    spi_write(0x04);   // Gain register
    spi_write(make8(value1,1)); // Send the high byte
    spi_write(make8(value1,0)); // Send the low byte
    output_high(DAC_CS); // Deselect the DAC
   
   dac_value = 65535;

    // Main loop
    while(TRUE) {
        // Write the example value to the DAC
        write_dac80501(dac_value);

        // Delay for demonstration purposes
        delay_ms(1000);
    }
}
Please help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Thu Jun 20, 2024 11:39 am     Reply with quote

You need a delay after sending reset. Minimum 250uSec.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Thu Jun 20, 2024 12:03 pm     Reply with quote

Brilliant. But where it is mentioned in the datasheet? Just curious.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Thu Jun 20, 2024 1:09 pm     Reply with quote

You have to put two things together.

8.3.3 Power-On-Reset (POR) where is says it takes 250uSec before a
command can be accepted.

Then the note in 8.3.4, "A software reset initiates a POR event."
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Thu Jun 20, 2024 2:18 pm     Reply with quote

Thank you Ttelmah Smile
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri Jun 21, 2024 7:27 am     Reply with quote

I'm also using the 24 bit ADC LTC2410 in the same project. ADC code is working fine separately.
When the ADC measured after the line

DAC init
Code:
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_64);
Then the ADC measurement is not correct.

ADC code:
Code:
signed int32 Read_A2D(void)
{
   int x;
   signed int32 data = 0;
   
   output_high(A2D_SCLK);
   delay_us(200);
   output_high(A2D_CSI);
   output_low(A2D_SCLK);
   output_low(A2D_CSI);
   
   data = 0;
   
   while((input(A2D_SDO))==1); //wait for /EOC to go low...
   
   for (x = 32; x!=0; x--)
   {
      output_high(A2D_SCLK); //clock hi
      delay_us(15);      //   15us it was
      if (input(A2D_SDO))
      bit_set(Data, x - 1);
      output_low(A2D_SCLK); //clock low
      delay_us(15);
      //      delay_us(10);
   }
   
   output_high(A2D_CSI);
   
   return data;
}
Any suggestions
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Fri Jun 21, 2024 9:40 am     Reply with quote

What pins are used for the ADC connection?.
You do realise just how good the electrical design is going to need to be
to work at these levels.
Are any interrupts enabled?.
Why the delays in the ADC sampling loop?. The times for this are nSec, not
uSec.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri Jun 21, 2024 9:47 am     Reply with quote

Testing code. But capturing ADC issue.
Code:
#include "18F2520.h"
#fuses HS
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// ADC PIN Assignments
#define A2D_CSI      PIN_C1     
#define A2D_SCLK    PIN_C3     
#define A2D_SDO      PIN_C4

// Define SPI pins for DAC80501
#define DAC_CS   PIN_C2
#define DAC_MOSI PIN_C5

#define RS485_EN   PIN_B1

#define DACREG 0x08 //command byte to select the data register

signed int32 A2D_value = 0;

// Function to initialize SPI for DAC80501
void init_spi(void) {
   setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_64);
   output_high(DAC_CS);  // Deselect DAC
}

// Function to write data to the DAC80501
void write_dac80501(unsigned int16 value)
{
    // Send the data to the DAC80501 over SPI
    output_low(DAC_CS); // Select the DAC
    spi_write(DACREG);
    spi_write(make8(value,1)); // Send the high byte
    spi_write(make8(value,0)); // Send the l     ow byte
    output_high(DAC_CS); // Deselect the DAC
}

signed int32 Read_A2D(void)
{
   int x;
   signed int32 data = 0;
   
   output_high(A2D_SCLK);
   delay_us(200);
   output_high(A2D_CSI);
   output_low(A2D_SCLK);
   output_low(A2D_CSI);
   
   data = 0;
   
   while((input(A2D_SDO))==1); //wait for /EOC to go low...
   
   for (x = 32; x!=0; x--)
   {
      output_high(A2D_SCLK); //clock hi
      delay_us(15);      //   15us it was
      if (input(A2D_SDO))
      bit_set(Data, x - 1);
      output_low(A2D_SCLK); //clock low
      delay_us(15);
   }
   
   output_high(A2D_CSI);
   
   return data;
}


void main() {
    unsigned int16 dac_value, value1;

   delay_ms(1000);

   output_high(RS485_EN);
   output_high(A2D_CSI);
   output_high(DAC_CS); // Deselect the DAC
   
   // Initialize SPI
    init_spi();
   
   // Send the data to the DAC80501 over SPI
   value1 = 0x000A;   // Soft reset
    output_low(DAC_CS); // Select the DAC
    spi_write(0x05);   // TRIGGER Register
    spi_write(make8(value1,1)); // Send the high byte
    spi_write(make8(value1,0)); // Send the low byte
    output_high(DAC_CS); // Deselect the DAC
   
   delay_ms(500);

    // Send the data to the DAC80501 over SPI
   value1 = 0x0100;   // REF-DIV divided by 2; Gain set to 1
    output_low(DAC_CS); // Select the DAC
    spi_write(0x04);   // Gain register
    spi_write(make8(value1,1)); // Send the high byte
    spi_write(make8(value1,0)); // Send the low byte
    output_high(DAC_CS); // Deselect the DAC
   delay_ms(100);

   dac_value = 65535;

    // Main loop
    while(TRUE) {
   

      A2D_value = Read_A2D();   
      delay_ms(200);
      
        write_dac80501(dac_value);

      printf("\r\naverage: %8Ld", A2D_value);
      delay_ms(1000);
    }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group