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 w/ ltc2440 A/D and pic16f877 interface

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Grimmjow



Joined: 15 Apr 2009
Posts: 10

View user's profile Send private message

problem w/ ltc2440 A/D and pic16f877 interface
PostPosted: Wed Apr 15, 2009 12:12 pm     Reply with quote

Hi there!!

I'm dealing w/ how to interface the ltc2440 A/D w/ pic16f877 by using the spi commands. I cannot find what's wrong w/ my code and I'm dealing with it for almost two full days Twisted Evil Code is below:

Code:
#include <16f877.h>
#fuses XT,NOPUT,NOWDT,NOPROTECT,NOLVP,BROWNOUT
#define use_portb_lcd TRUE
#use delay (clock=4M)
#include <lcd.c>

#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)

#define _CS PIN_D0    //select ADC     
#define BUSY PIN_D1

#byte SSPSTAT=0x94
#byte SSPCON=0x14

#bit CKE=SSPSTAT.6
#bit CKP=SSPCON.4

int SampRateADC=0x78; //sampling rate is selected as 6.875Hz


struct fourbytes
{
int8 te0;
int8 te1;
int8 te2;
int8 te3;
};

union
{
signed int32 bits32;
struct fourbytes by;
} voltage;


float temperature;

void initialize(void);
void ReadADC(void);
void show(void);

void main()
{
   initialize();   
     
   while(true) {
     
       output_low(_CS);
       while(input(BUSY)){};
       ReadADC();
       //getdatabytes();
       output_high(_CS);
       voltage.bits32 = (voltage.bits32>>5)&(0b00000000111111111111111111111111);
       temperature=(float)voltage.bits32;
       temperature=temperature*0.17881393*0.001; //turned into analog
       show();
   }
}

void initialize(){
   lcd_init();
   delay_ms(6);
   setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_4);
   output_bit(CKP,0); //data at rising edge
   output_bit(CKE,1);
}

void ReadADC(){

   spi_write(SampRateADC);
   while(!spi_data_is_in()){};
   voltage.by.te3=spi_read();

   spi_write(SampRateADC);
   while(!spi_data_is_in()){};
   voltage.by.te2=spi_read();
   
   spi_write(SampRateADC);
   while(!spi_data_is_in()){};
   voltage.by.te1=spi_read();
   
   spi_write(SampRateADC);
   while(!spi_data_is_in()){};
   voltage.by.te0=spi_read();
   
}


void show(){
      lcd_gotoxy(1,1);
      printf(lcd_putc,"\f temperature is = \n %f Celcius",temperature);
      delay_ms(2);
}


Resulting pulses are also in the link below:


yellow-> SCK;
blue->SDI;
red->SDO;
green->busy.

Problem here is, I cannot get a constant data. When I try to see the result in the LCD, I see 5-6 different results instead of one result. In other words, SDI is not stable!! I think I cannot synchronize the data stream in the ReadADC(). I don't know built-in spi functions very well.

Any help would be appreciated Smile
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 16, 2009 12:59 am     Reply with quote

Quote:
setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_4);
output_bit(CKP,0); //data at rising edge
output_bit(CKE,1);

The LTC2440 operates in SPI Mode 0. You should get rid of the lines
above and use the following code:
Code:
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);

Note that the CKP and CKE lines are removed.

Quote:
void ReadADC(){

spi_write(SampRateADC);
while(!spi_data_is_in()){};
voltage.by.te3=spi_read();

etc.

Your ReadADC() code is too complex and doesn't match the sample
CCS code in their AN96 appnote. See page 14 of the appnote.
It should be done like this:
Code:

void ReadADC()
{
   voltage.by.te3=spi_read(SampRateADC);
   voltage.by.te2=spi_read(0);
   voltage.by.te1=spi_read(0);
   voltage.by.te0=spi_read(0);
}



Quote:
#define BUSY PIN_D1

while(input(BUSY)){};

In their sample code, and in the data sheet, they want you to poll the
SDI pin on the PIC. The #define BUSY statement should be changed to
use pin C4.

AN96 can be downloaded from this page:
http://www.linear.com/pc/productDetail.jsp?navId=H0,C1,C1155,C1001,C1152,P1771


Regarding external the connections:
Make sure you have a stable reference voltage connected to the REF+
pin on the LTC2440. It's probably easiest to connect it to the Vdd
voltage. Connect the REF- pin to ground.
Also make sure the \EXT pin on the LTC2440 is connected to ground.


I didn't look at your math code. I would just try to display the raw
value received from the ADC for the initial tests. Display it as a
32-bit hex value every 500 ms. Then if that works, add your math code.
Grimmjow



Joined: 15 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Thu Apr 16, 2009 12:34 pm     Reply with quote

First of all, thanks for the quick reply Smile

I did everything that you said to me PCM programmer...My new code looks like;

Code:
#include <16f877.h>
#fuses XT,NOPUT,NOWDT,NOPROTECT,NOLVP,BROWNOUT
#define use_portb_lcd TRUE
#use delay (clock=4M)
#include <lcd.c>

#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)

#define _CS PIN_D0         
#define BUSY PIN_C4

#byte SSPSTAT=0x94
#byte SSPCON=0x14

#bit CKE=SSPSTAT.6
#bit CKP=SSPCON.4

int SampRateADC=0x78;


struct fourbytes
{
int8 te0;
int8 te1;
int8 te2;
int8 te3;
};

union
{
signed int32 bits32;
struct fourbytes by;
} voltage;

float temperature;

void initialize(void);
void ReadADC(void);
void show(void);

void main()
{
   initialize();   
     
   while(true) {
     
       output_low(_CS);
       while(input(BUSY)){};
       ReadADC();
       output_high(_CS);
        show();
   }
}

void initialize(){
   lcd_init();
   delay_ms(6);
   setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
   
}

void ReadADC(){
 
   voltage.by.te3=spi_read(SampRateADC); 
   voltage.by.te2=spi_read(0);     
   voltage.by.te1=spi_read(0);   
   voltage.by.te0=spi_read(0);
   
}


void show(){
      lcd_gotoxy(1,1);
      printf(lcd_putc,"\f temperature is = \n %LX Celcius",voltage.bits32);//temperature);
      delay_ms(500);
}


According to these, my pulses changed as;


but still, same problem exists.

I don't think there is something wrong w/ the code. Therefore, I will have few questions:

1) You said that "In their sample code, and in the data sheet, they want you to poll the
SDI pin on the PIC. The #define BUSY statement should be changed to
use pin C4. "
Then what does the "busy" pin stands for?? Also, when I do it with either pin_d1 or pin_c4, I get pretty much the same result:sad:

2) Now, I'm wondering whether my hardware is right or wrong. So; my connections are:


Could you tell me is there a mistake?? B/c I have to do this as soon as possible in order to enhance this project.

Thanks again Smile
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 16, 2009 1:25 pm     Reply with quote

Quote:
Then what does the "busy" pin stands for??

The BUSY signal is only used if the EXT pin is tied high.
The LTC2440 data sheet says:
Quote:

If EXT is tied high, the internal serial clock mode is selected.
The device generates its own SCK signal and outputs this on
the SCK pin. A framing signal BUSY (Pin 15) goes low indicating
data is being output.

You are using external SCK (generated by the PIC), and the
EXT pin is tied low for this mode. So BUSY is not used in your design.

You are using a simulator, so we don't know if the simulator has
bugs in the LTC2440 simulation.

You're missing the crystal, its capacitors, and the MCLR pull-up
resistor on the PIC. Is this allowed by the simulator ?

Initially, try setting VREF+ to the same as the Vdd voltage (+5v).
Grimmjow



Joined: 15 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Thu Apr 16, 2009 5:51 pm     Reply with quote

First of all, thanks for the explanation about the BUSY pin...Things are a bit more clear now..

Quote:
You are using a simulator, so we don't know if the simulator has
bugs in the LTC2440 simulation.


Yes, you're right...But the simulator that I'm using has only one 24-bit ADC. So, I have to rely on it for the time-being.

Quote:
You're missing the crystal, its capacitors, and the MCLR pull-up
resistor on the PIC. Is this allowed by the simulator ?


Yes, simulator allows this sort of things. These are not problem in virtual world...

I disconnected the BUSY pin, and tried again but nothing has changed.

The real problem that I'm dealing w/ is; I don't want to set/clear every single bit(therefore switch) in the pic manually(like I did in the previous code such as CKE,CKP etc.) in order to communicate through spi. I wanna use and understand the built-in functions of the CCS-C. Otherwise, I would use assembly.

If I cannot communicate via these built-in functions, I'll most probably start to use fast_io and program bit-by-bit. But then, as I said before, what's the meaning of using CCS-C if you cannot utilize these flexibilities??

If you still have any ideas or suggestions, I would really appreciate it Smile Otherwise, I would start to write the code with a new point of view which I do not prefer Sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 16, 2009 6:01 pm     Reply with quote

Post your compiler version.
Grimmjow



Joined: 15 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 9:44 am     Reply with quote

Here is the version:

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 11:31 am     Reply with quote

Quote:
void show(){
lcd_gotoxy(1,1);
printf(lcd_putc,"\f temperature is = \n %LX Celcius",voltage.bits32);//temperature);
delay_ms(500);
}

Post some of the values that are displayed by the printf statement.
Grimmjow



Joined: 15 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 11:46 am     Reply with quote

Some of the values are:

02415C44
22415C04
22015C04
22015844
20015044
20414044
20414444
22410C44
22400C40
02401C40

After this sequence, it starts all over again. This is for Vin=0.21V for Vref=3V. So, range is +-1.5V. For every voltage, it has this kind of voltage sequence instead of having a single value.

By the way, there is no math code applied.

Thanks a lot again...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 1:09 pm     Reply with quote

I would simplify the test environment. Get rid of the LM35 temperature
sensor, and connect the VIN+ pin of the LTC2440 to ground.

Also, don't use a Vref that is lower than the Vcc of the LTC2440.
The schematic doesn't show the Vcc pin. I assume it's set to +5v.
If so, set VREF+ to +5v. Then run the test and post the output again.
Grimmjow



Joined: 15 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 2:30 pm     Reply with quote

I did exactly what you said. BTW; yes Vcc is set to 5V.

Here are the results:

037E0F78
077E1F78
077C1F70
0F783F62
1F787F66
1F717F46
1F637F0E
1F637E1E
1F477C1E
1F0F7C3E
1E1F787E
1C1F717E
1C3F737E
187F637E
117F477C
137F0F7C

Now, data starts repeating...Ok, now I'm confused Shocked At first data set, there was ten data...Now there is sixteen. In other words, as range increased; number of repeating data increased as well.

Thanks again for your help...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 3:15 pm     Reply with quote

It runs continuously, displaying the output every 500 ms.
If you run it for 8 seconds, you get 16 numbers out.

I'm not sure what else I can do. I think your current code looks close
to their sample code in AN96. I begin to suspect the simulation of the
LTC2440 has a problem. I can't do anything about that.
Grimmjow



Joined: 15 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Fri Apr 17, 2009 4:33 pm     Reply with quote

Ok; thanks a lot for your effort...

If(or when) I solve the problem; I will post it for the next generations Laughing
Grimmjow



Joined: 15 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Tue Apr 21, 2009 6:46 am     Reply with quote

I started to doubt that simulator has bug with the ltc2440 model. So, i tried pretty much the same code with ltc1864(16-bit ADC with spi).

Code is as follows:

Code:
#include <16f877.h>
#fuses XT,NOPUT,NOWDT,NOPROTECT,NOLVP,BROWNOUT
#define use_portb_lcd TRUE
#use delay (clock=4M)
#include <lcd.c>

#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)

#define CONV PIN_D0

int8 MSB;
int8 LSB;
int16 data;

void initialize(void);
void ReadADC(void);
void show(void);

void main()
{
     
   initialize();
   
   while(True){
   
   ReadADC();
   delay_us(50);
   show();
   
   }   
}

void initialize(){
   
   output_low(CONV);
   lcd_init();
   delay_ms(6);
   setup_timer_2(T2_DIV_BY_16,124,1); // timer is 500 Hz
   setup_spi(SPI_MASTER | SPI_MODE_3 | SPI_CLK_T2);
   

}

void ReadADC(){

   output_high(CONV);
   delay_us(30);
   output_low(CONV);
   MSB=spi_read(0);
   LSB=spi_read(0);
   data=make16(MSB,LSB);
   
}

void show(){
      lcd_gotoxy(1,1);
      printf(lcd_putc,"\f Data is = \n %LX Hex",data);
      delay_ms(2);
}


This code works in simulator w/ ltc1864 without any problem. Therefore, i decided to quit trying it with ltc2440 since I may be dealing with a buggy model Smile

I believe this may enlight some people who may have encountered with the same problem...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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