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

problem in interfacing LTC2410 with 18LF2520
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
temtronic



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

View user's profile Send private message

PostPosted: Thu Jul 09, 2015 5:17 am     Reply with quote

I have to agree with Mt. T about PCB layout, power supply design, etc. in dealing with ADC chips!!

Simple test, connect Vin+ and Vin- to ground. sample and display 256 times. You should get 0 everytime or within +-1 or 2 bits. If not you have an 'analog' problem. Noise, layout, bad ground, EMI, the list is long....
Do the same test using a battery to see how the 'top end' of the ADC performs as well.


Designing rock stable ADC of more than 10 bits is half engineering, half 'art'. You can easily spend weeks getting the PCB 'almost right...

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 20061

View user's profile Send private message

PostPosted: Thu Jul 09, 2015 7:35 am     Reply with quote

First, the routine should be returning signed. You are handing it a signed value but declaring the routine as returning unsigned (the default). Keep your signing tidy. Look at how I do the sign conversion. What I do is declare both a signed variable, and an unsigned variable to sit in the same memory space (the union). Then clock the data into the unsigned variable (it is unsigned as far as the logic goes), test the sign bit, extend this into the high bits as required, and then return the result as a signed variable.

Then remember what I said about /32.

The chip returns 5 bits after it's last useable bit. They call these extra bit 'sub Lsb' bits.

Then you are back to operating CS. Doing it this way you need to be operating in the Figure 5 clocking. Pulsing CS low, and testing if SDO (SDI on the PIC) is taken low (which signals that the conversion has completed). It'll go to sleep after the conversion has completed.

Seriously, again, why not use the SPI routines. Much simpler, and faster.

SPI version using CS:
Code:

#include "18F2520.h"
#fuses INTRC, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP      // Internal oscillator
#use delay(clock=1000000)      // 1Mhz

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

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

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_SCO);
      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
   //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
          oversample=0;
          for (ctr=0;ctr<64;ctr++)
             oversample+=Read_A2D();
          //Now perform simple *64 averaging.
          A2D_value=oversample/64;
          // display the adc value on lcd
          //remember this is a _signed_ value
   }
}


There was one big mistake in my previous code, I was only converting to a 16bit signed, not 32. Corrected here.

Now the unit returns a range of Vref (-0.5Vref to +0.5Vref), for a 25 bit result. 24bits for each half Vref range. Each count is just under 0.2uV. Now seriously you post the Vref to four decimals (implying a 5 digit DVM), but a _single_ count on your DVM, will be 500 counts on this chip!.....

Also, this will see signals far faster than your DVM. Most DVM's take a large fraction of a second to sample. This chip works hundreds of times faster, so the DVM, will not 'see' signals that this will record.

You are a long way from understanding just how hard 24bit operation is!.

I've corrected the sign extension, and added 64* averaging to this.

Note that I'm taking advantage of the fact that you can read the state of the SPI input pin when it is configured as SPI, without changing anything. Smile
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Sat Jul 18, 2015 12:48 am     Reply with quote

Thanks Ttelmah. I have used your code.

Below are the results.
Value changes like 24212, 23622, 26192, 26997, 22319, 27021, ...

@temtronic: I used the Ttelmah code and IN+ and IN- are shorted to ground.
Results are -1195, -1203, -1226, -1206, -1205, -1181, -1190, ...
Ttelmah



Joined: 11 Mar 2010
Posts: 20061

View user's profile Send private message

PostPosted: Sat Jul 18, 2015 12:57 am     Reply with quote

Just 220uV difference between the two terminals. Varying by about +/-about 4.5uV. Not bad.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Tue Jul 28, 2015 12:26 am     Reply with quote

I am here with another problem with LTC2410.

Supply voltage: 3.3V
IN+ = 0.696V; IN- = 0.696V.
REF+ = 0.250V; REF- = 0V.

Output code from LTC2410 is saturated for this input voltage. Why is it so? Please help.

When i increase the voltage at IN+ by 50mV, the code remains the same.
Ttelmah



Joined: 11 Mar 2010
Posts: 20061

View user's profile Send private message

PostPosted: Tue Jul 28, 2015 12:41 am     Reply with quote

Look at the data sheet.

What is the input range specified as relative to the Vref?.

"ANALOG INPUT RANGE –0.5VREF TO 0.5VREF"

Of course it is saturated.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Tue Jul 28, 2015 12:59 am     Reply with quote

In datasheet it say,

*The differential input voltage VIN = IN+ – IN–.
**The differential reference voltage VREF = REF+ – REF–.

Vin = 0.696 - 0.696 => 0V
Vref = 0.250-0 => 0.250V

-0.5* 0.25 => -0.125
+0.5*0.25 => +0.125

Vin is in between the -0.5 x Vref to 0.5* Vref.

Please correct if im wrong.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Tue Jul 28, 2015 9:51 pm     Reply with quote

output code from the LTC2410 is always
0b11111111111111111111111111111

Why it is behaving like this. Am I missing something?
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