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 Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Fri Jun 21, 2024 11:10 am     Reply with quote

The answer is very obvious. You are using the hardware SPI for the DAC.
This uses pins C3, C4 & C5. You then try to use C5 for the software SPI to
the ADC. No wonder it gives problems.

WHY????

Use the hardware SPI for both devices. Separate CS lines. If they need
different modes, then setup two configurations (use #use SPI not
setup_spi, and give these different stream names).
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri Jun 21, 2024 11:23 am     Reply with quote

how to use #use spi
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Fri Jun 21, 2024 11:28 am     Reply with quote

Read the manual, and look at the examples.
Unless you have a very old compiler, this is the preferred way to configure
SPI now. Beware though you need to use spi_xfer instead of spi_read or
spi_write.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri Jun 21, 2024 12:36 pm     Reply with quote

Something like this,
Code:
#define DAC_CS PIN_C2
#define ADC_CS PIN_C1

#use SPI(MASTER, SPI1, MODE=0, BITS=32, STREAM=SPI_ADC)
#use SPI(MASTER, SPI1, MODE=0, BITS=16, STREAM=SPI_DAC)

It would be helpful if you help me to modify the earlier code.

How to receive 32 bit from ADC?
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Fri Jun 21, 2024 4:13 pm     Reply with quote

Does the below code is fine. Please comment.
Code:
#include <18F2520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, ERRORS)

// Define your DAC and ADC chip select pins
#define DAC_CS PIN_C2
#define ADC_CS PIN_C1

#define SDI   PIN_C4

#use SPI(MASTER, MODE=0, FORCE_HW, BITS=24, STREAM=DAC) //defaults to maximum speed
#use SPI(MASTER, MODE=0, BITS=32, STREAM=ADC) //defaults to maximum speed

void main() {
    unsigned int16 dac_value = 0;
   int32 dummy;
   int32 adc_value;

    delay_ms(2000);
   printf("\r\nmain");

    // Example DAC initialization
   output_high(ADC_CS);  // Ensure ADC chip select is initially high
    output_high(DAC_CS);  // Ensure DAC chip select is initially high

    printf("\r\nWelcome");
    delay_ms(500);

    // DAC configuration steps
    output_low(DAC_CS); // Select the DAC
   dummy=spi_xfer(DAC,0x05000A,24);
    output_high(DAC_CS); // Deselect the DAC
    delay_ms(500);

    printf("\r\nDAC step 1 done");
    delay_ms(500);

    output_low(DAC_CS); // Select the DAC
   dummy=spi_xfer(DAC,0x040000,24);
    output_high(DAC_CS); // Deselect the DAC

    printf("\r\nDAC step 2 done");
    delay_ms(500);

   dac_value = 65535;

    // Main loop for DAC operation
    while (1) {
        printf("\r\nwhile loop");
        delay_ms(500);

        // Example DAC write operation
        output_low(DAC_CS);  // Select DAC
      dummy = spi_xfer(DAC,0x8, 8);  // Write data to DAC
        dummy = spi_xfer(DAC,dac_value, 16);  // Write data to DAC
        output_high(DAC_CS);  // Deselect DAC

        // Example ADC read operation (if ADC is connected and configured)
        // Uncomment and complete ADC functionality if needed
   
        output_low(ADC_CS);  // Select ADC
      spi_xfer(ADC, 0xFFFFFFFF, 32); // Send dummy data to start conversion
//        adc_value = spi_xfer(ADC, 0x00000000, 32);  // Read ADC value
        output_high(ADC_CS);  // Deselect ADC

      while((input(SDI))==1); //wait for /EOC to go low...
   
       output_low(ADC_CS);  // Select ADC
        adc_value = spi_xfer(ADC, 0x00000000, 32);  // Read ADC value
        output_high(ADC_CS);  // Deselect ADC

        printf("\r\nADC Value: %ld", adc_value);
 
        printf("\r\nDAC Value: %lu", dac_value);
        delay_ms(500);  // Example delay
    }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Sat Jun 22, 2024 4:12 am     Reply with quote

A couple of comments/questions:

Are you sure of the mode numbers. Need to check the data sheet for both
devices.
Will both support the maximum SPI rate?. Again need to check the data
sheet.

Code:

#use SPI(MASTER, MODE=0, SPI1, BITS=24, STREAM=DAC) //defaults to maximum speed
#use SPI(MASTER, SPI1, MODE=0, BITS=32, STREAM=ADC) //defaults to maximum speed


You need to tell it what SPI port or pins to use. SPI1 says to use the SPI1
hardware port. Also forces hardware.

If both devices do support the same mode, you can just use one #use,
and the same stream name. The point about using separate streams is
it allows different modes/speeds for the two devices. Leave bits=32,
since you specify the bits used in each transfer..
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Sun Jun 23, 2024 8:24 am     Reply with quote

I modified the code. DAC is working good. But ADC is not working as expected. Receiving 0 in ADC.

Please support.
Code:

#include "18F2520.h"
#fuses HS
#use delay(clock=12000000)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7,ERRORS)

#define A2D_CSI       PIN_C1     
#define A2D_SCLK      PIN_C3     
#define A2D_SDO       PIN_C4   

#use spi(MASTER, DI=PIN_C4, CLK=A2D_SCLK, MODE=0, BAUD=19200, stream=LTC)
#use spi(MASTER, FORCE_HW, MODE=0, stream=DAC)

// DAC PIN Assignments
#define DAC_CS      PIN_C2
#define DAC_MOSI   PIN_C5

#define RS485_EN   PIN_B1      // RS485 transmit or receive enable pin
#define OUT_CNTRL   PIN_B3      // Voltage or current output selection pin

signed int32 A2D_value = 0;

void main()
{
   unsigned int32 dummy = 0;
   unsigned int32 dac_value = 0;
   signed int32 adc_value = 0;

   output_high(RS485_EN);
   delay_ms(50);
   printf("\n\r");
   printf("\r\nMain loop\r\n");
   output_low(RS485_EN);
   delay_ms(50);

   output_low(OUT_CNTRL);

    // Initialize SPI
   output_low(DAC_CS); // Select the DAC
   dummy=spi_xfer(DAC,0x05000A,24);
    output_high(DAC_CS); // Deselect the DAC
    delay_ms(500);

    printf("\r\nDAC step 1 done");
    delay_ms(500);

    output_low(DAC_CS); // Select the DAC
   dummy=spi_xfer(DAC,0x040000,24);
    output_high(DAC_CS); // Deselect the DAC

   dac_value = 16383;

   while(1)
   {   
      // DAC TEST
        output_low(DAC_CS);  // Select DAC
      dummy = spi_xfer(DAC,0x8, 8);  // Write data to DAC
        dummy = spi_xfer(DAC,dac_value, 16);  // Write data to DAC
        output_high(DAC_CS);  // Deselect DAC

      output_high(RS485_EN);
      delay_ms(50);
      printf("\n\r");
      printf("\r\nDAC Value = %6lu\r\n", dac_value);
      output_low(RS485_EN);
      delay_ms(50);
      delay_ms(500);

      // ADC TEST
      adc_value = 0;
      output_low(A2D_CSI);  // Select ADC
      while (input(A2D_SDO) == 1);
      adc_value = spi_xfer(LTC, 0x00000000, 32);  // Read ADC value
      output_high(A2D_CSI);  // Deselect ADC
      
      output_high(RS485_EN);
      delay_ms(50);
      printf("\n\r");
      printf("\r\nADC Value = %9ld\r\n", adc_value);
      output_low(RS485_EN);
      delay_ms(50);
      delay_ms(500);  // Example delay
   }
}
temtronic



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

View user's profile Send private message

PostPosted: Sun Jun 23, 2024 2:16 pm     Reply with quote

curious... so....I got the LTCdatasheet

possible problems
1) wrong SPI 'mode'
2) wrong connections
3) grounded ADC input pin
4) SPI speed too fast

I notice you didn't parse the 32 data from the ADC. That should be done !
testing should be done with a known, stable Vin to the ADC, say from a Vreg chip ( 1.2500000000 volts ). That way you know what it's supposed to be.
24 bit ADC is mighty 'tricky' to get good ,let alone GREAT results from.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Sun Jun 23, 2024 2:45 pm     Reply with quote

Connections are good. Now I can able to see positive results. But will do full testing and confirm. Final modified code. any problems do you see visually.
Code:
#include "18F2520.h"
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP      // Internal oscillator
#use delay(clock=12000000)      // 12Mhz
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7,ERRORS)

#define A2D_CSI       PIN_C1     
#define A2D_SCLK      PIN_C3     
#define A2D_SDO      PIN_C4 

#define RS485_EN   PIN_B1
#define DAC_CS      PIN_C2
#define OUT_CNTRL   PIN_B3

#use spi(MASTER, DI=A2D_SDO, CLK=A2D_SCLK, BAUD=100000, BITS=32, MODE=1, stream=LTC)
#use spi(MASTER, DO=PIN_C5, CLK=A2D_SCLK, MODE=0, BAUD=100000, stream=DAC)

signed int32 Read_A2D(void)
{
   int1 eoc;
   union
   {
      signed int32 rval;
      unsigned int32 raw;
   } temp=0;
   do
   {
      output_low(A2D_CSI);
      eoc = input_state(A2D_SDO);
      output_high(A2D_CSI); //clock in the EOC bit
   } while (eoc); //wait for EOC to drop
   output_low(A2D_CSI); //now drop select for the transfer
   temp.raw=spi_xfer(LTC,0,32); //get 32bits
   output_high(A2D_CSI);

   //Now need to sign extend the value
   if (bit_test(temp.raw,29))
   {
      //-ve value
      temp.raw |=0xE0000000; //turn on top 3 bits
   }
   else
   {
      temp.raw &=0x01FFFFFFF; //only use low 29bits
   }
   return temp.rval/32;
}
   

void main(void)
{
   signed int32 A2D_value;
   signed int32 oversample;
   int8 ctr;
   setup_adc_ports(NO_ANALOGS|VSS_VDD);         // No analogs
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   output_high(A2D_CSI);
   
   setup_comparator (NC_NC_NC_NC);      // Disable comparator

   unsigned int32 dummy = 0;
   unsigned int32 dac_value = 0;

   output_high(RS485_EN);
   delay_ms(50);
   printf("\n\r");
   printf("\r\nMain loop\r\n");
   output_low(RS485_EN);
   delay_ms(50);

   output_low(OUT_CNTRL);

        // Initialize SPI
   output_low(DAC_CS); // Select the DAC
   dummy=spi_xfer(DAC,0x05000A,24);
        output_high(DAC_CS); // Deselect the DAC
        delay_ms(500);

        printf("\r\nDAC step 1 done");
        delay_ms(500);

        output_low(DAC_CS); // Select the DAC
   dummy=spi_xfer(DAC,0x040000,24);
        output_high(DAC_CS); // Deselect the DAC

   dac_value = 16383;

       //Now need to trigger a dummy read to start the conversion
      A2D_value=Read_A2D();


   while(1)
   {
          delay_ms(200); //delay before reading the first time
          A2D_value=Read_A2D();
   
    A2D_value = A2D_value/8;

   output_high(RS485_EN);
   delay_ms(50);
   printf("ADC: %8Ld\r\n", A2D_value);
   printf("\n\r");
   output_low(RS485_EN);
   delay_ms(50);

   // DAC TEST
        output_low(DAC_CS);  // Select DAC
      dummy = spi_xfer(DAC,0x8, 8);  // Write data to DAC
        dummy = spi_xfer(DAC,dac_value, 16);  // Write data to DAC
        output_high(DAC_CS);  // Deselect DAC

      output_high(RS485_EN);
      delay_ms(50);
//      printf("\n\r");
//      printf("\r\nDAC Value = %6lu\r\n", dac_value);
      output_low(RS485_EN);
      delay_ms(50);

      delay_ms(500);
   }
}
temtronic



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

View user's profile Send private message

PostPosted: Sun Jun 23, 2024 4:02 pm     Reply with quote

you need to mask off the top 3 bits as they're NOT part of the reading.
you can also eliminate the lower 5 bits. what's left is the 24 bits of the A2D voltage, using bit29 as the 'sign' bit.
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Mon Jun 24, 2024 1:04 am     Reply with quote

Also, the baud rate is wrong.
19200 is the frequency of it's internal SCK. External SCK, supports rates
up to 2MHz. Select this. or close to it (1Mhz say).

The mode number is wrong. Thought it was likely.
The LTC says it outputs data on the falling edge of the clock, and expects
it to be sampled on the rising edge. This is MODE3.
For this look at the Wikipedia entry, and particularly the table under the
section 'mode numbers.
The DAC actually wants MODE1. That it works on 0, suggests a lot of
luck (actually that the PIC has it's clock very slightly delayed compared
to the data).
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 Previous  1, 2
Page 2 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