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

LIS302DL Accelerometer

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



Joined: 21 Apr 2008
Posts: 18

View user's profile Send private message

LIS302DL Accelerometer
PostPosted: Wed Feb 04, 2009 1:13 am     Reply with quote

Hello, I am trying to get a PIC 16F690 to communicate with an LIS302DL Accelerometer through SPI interface. I have been trying all the things I can think of but am unable to get them to talk to each other.

Below is the code I have been trying. I have searched the forum the best I can and have borrowed code from some posts. All I am trying to do is to get the X axis to display on an LCD. All I am getting on the LCD is 255 and it does not change.
Code:
#include <16f690.h>
#device adc=10
#fuses HS, PUT, NOWDT, brownout
#use delay(clock=4000000)
#include <Flex_lcd.c>

#define ACC_CS Pin_C6

// SPI modes
#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)

int8 hex;

int8 Acc_Read_Register(int8 reg)
{
int8 data;

output_low(ACC_CS);
spi_write(reg);
data = spi_read(0);
output_high(ACC_CS);

return(data);
}

void Acc_Write_Register(int8 add, int8 reg)
{
output_low(ACC_CS);
spi_write(add);
spi_write(reg);
output_high(ACC_CS);
}

void main()
{
   int8 Xdata;
   
   setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);

   setup_oscillator (OSC_4MHZ);

   delay_ms(10);
   
   lcd_init ();
   
   while(1){
   
   hex = (0x29);
   
   Xdata = Acc_Read_Register(hex);
   
   delay_ms(500);
     
   printf (lcd_putc, "\f%UX",xdata);
   
   };
}


Any suggestions would be appreciated.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 04, 2009 1:59 am     Reply with quote

The LIS302DL data sheet shows that it uses SPI mode 3, not mode 0.
http://www.st.com/stonline/products/literature/ds/12726.pdf
Look at the timing diagrams on page 22 of the link above.
It shows that the clock (SPC) idles at a high level and does a positive
transition in the middle of each data cell. Look at the SPI timing
diagrams on each of these web pages below. That's SPI mode 3.
http://www.totalphase.com/support/kb/10045/#modes
http://elm-chan.org/docs/spi_e.html

Next, you are trying to read register 0x29. But look at figure 7 on
page 22 of the LIS302DL data sheet. It shows that for a read operation
the first bit out (the MSB) is supposed to be a '1' bit. But you have it
as a '0'. You need to bitwise-OR it with 0x80 to set that bit = 1.
See the line in bold below for the required changes.
Quote:
int8 Acc_Read_Register(int8 reg)
{
int8 data;

output_low(ACC_CS);
spi_write(reg | 0x80); // Combine with Read bit.
data = spi_read(0);
output_high(ACC_CS);

return(data);
}


There might be other problems, but at a minimum you need to fix these
two things.
treanla
Guest







Chip not active
PostPosted: Wed Feb 04, 2009 2:07 am     Reply with quote

Hi,
I have it up and running on a 18f2580.

There are a few things:

1. Due to an errata in 18f2580, I need a NOP between the spi statements otherwise the chip will hang. Not sure if this applies to your chip also.
Example:
spi_write( 0x0f );
#asm
nop
#endasm
data = spi_read(0);

2. You must initialize the chip, its default turned off.
Set your preferences in register 0x20 and 0x21
See page 31-34 in the datasheet.

3. I don't see that you have prepared for the read/write flag that you must set when dealing with the registers.
See page 26 in the datasheet.
(To save you some time.. OR the reg value with0x80 to the the chip you want to read the value at the adress you are sending)

Enjoy
/Anders
williefeb_19



Joined: 21 Apr 2008
Posts: 18

View user's profile Send private message

PostPosted: Thu Feb 05, 2009 3:13 am     Reply with quote

Thank you both for replying.

I have been trying the bitwise OR with no success. The NOP statement doesn’t make any difference either. I am starting to think that the LIS302DL may be bad. I have checked my connections multiple times. I have tried a few different settings for the 0x20 and 0x21 register.

Even when I try to read the “Who Am I” register I only get 255 when I think I should be getting 59.
treanla
Guest







my setup..
PostPosted: Thu Feb 05, 2009 6:32 am     Reply with quote

I have the following:
Code:

setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_16|SPI_XMIT_L_TO_H);

settings up registers:
0x20: Bit values 0x01+0x02+0x04+0x80
0x21: Bit values 0x40

Code:
int read_reg( int reg )
   {
   output_low( CS_LISDL );
   spi_write( 128|reg  );
   #asm
   nop            // a must for my chip, may not be needed for others
   #endasm
   c = spi_read(0x00);
   output_high( CS_LISDL );
   return c;
   }


Code:

void write_reg( int reg,data )
   {
   output_low( CS_LISDL );
   spi_write( reg );
   #asm
   nop          //not needed for all chips, see errata
   #endasm
   spi_write(data);
   output_high( CS_LISDL );
   }
williefeb_19



Joined: 21 Apr 2008
Posts: 18

View user's profile Send private message

PostPosted: Fri Feb 06, 2009 2:07 am     Reply with quote

Here's my Updated code and I am still getting 255 on the LCD. I think I am going to order another one and give it another try.

Code:
#include <16f690.h>
//#device adc=10
#fuses HS, PUT, NOWDT, brownout
#use delay(clock=4000000)
#include <Flex_lcd.c>

#define ACC_CS Pin_C6

// SPI modes
#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)

int count;

int Acc_Read_Register(int reg)
{
int data;

output_low(ACC_CS);
spi_write(reg | 0x80);
data = spi_read(0x00);
output_high(ACC_CS);

return(data);
}

void Acc_Write_Register(int add, int reg)
{
output_low(ACC_CS);
spi_write(add);
spi_write(reg);
output_high(ACC_CS);
}

void main()
{
   int Xdata;
   
   setup_spi(SPI_MASTER | SPI_MODE_3 | SPI_CLK_DIV_16);
   delay_ms(50);

   setup_oscillator (OSC_4MHZ);
   
   lcd_init ();
   
   Acc_Write_Register(0x20, 0x87);
   Acc_Write_Register(0x21, 0x40);
   
   count = 0;
   
   while(1){
   
   count++;
   
   Xdata = Acc_Read_Register(0x29);
   
   delay_ms(250);
     
   printf (lcd_putc, "\f%UX %UCOUNT",Xdata, count); //display X data and Count
   
   };
}


Last edited by williefeb_19 on Sat Feb 07, 2009 1:06 am; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 06, 2009 2:36 am     Reply with quote

Quote:

while(1){

count++;

Acc_Read_Register(0x29);

delay_ms(250);

printf (lcd_putc, "\f%UX %UCOUNT",Xdata, count); //display X data and Count

};

You're never loading Xdata with anything. You've got to take the return
value from the read function and put it into Xdata. Example:
Code:
Xdata = Acc_Read_Register(0x29);


I didn't check any other aspects of your program. But at least this one
thing must be fixed.
williefeb_19



Joined: 21 Apr 2008
Posts: 18

View user's profile Send private message

PostPosted: Sat Feb 07, 2009 1:05 am     Reply with quote

Code:
Xdata = Acc_Read_Register(0x29);


Sorry about that the code was there when I was testing, just missed it when I copy and pasted. I've added it to the above source.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Feb 07, 2009 1:41 am     Reply with quote

But what about Treanla's comment about the power-down mode ?
The chip is powered-down by default. Here's what the manual says:
Quote:
7.2 CTRL_REG1 (20h)

PD Power Down Control. Default value: 0
(0: power down mode; 1: active mode)

The PD bit is bit 6 in register 0x20.

You are doing this initialization:
Quote:

Acc_Write_Register(0x20, 0x87);
Acc_Write_Register(0x21, 0x40);

To remove the power-down condition, it should really be:
Quote:

Acc_Write_Register(0x20, 0xC7);
Acc_Write_Register(0x21, 0x40);


Also, in Table 2.2, the data sheet says that there is a "Turn on" time
after exiting power-down mode of 3/ODR, where "ODR" is the data rate.
You have set the data rate to 400 Hz. Therefore 3/400 = 7.5 ms.
So there really should be a delay placed after the write operation to
register 0x20. These should be the changes:
Quote:

Acc_Write_Register(0x20, 0xC7);
delay_ms(10);
Acc_Write_Register(0x21, 0x40);

There might be other things required. You need to read the data sheet.
williefeb_19



Joined: 21 Apr 2008
Posts: 18

View user's profile Send private message

PostPosted: Sun Feb 08, 2009 2:26 am     Reply with quote

I have been looking at the data sheet. This is only the second SPI device I have used. The other device I only had to write to and never read. (http://ccsinfo.com/forum/viewtopic.php?t=34559&highlight=)
I've made the changes to the code and I am still getting nothing from the X axis or the "Who Am I" Register. Even with the registers the way they where before shouldnt I be getting something other than 255 all the time?

Thanks Again
balajivenu



Joined: 12 May 2010
Posts: 2
Location: India

View user's profile Send private message Send e-mail Visit poster's website

Check
PostPosted: Wed May 12, 2010 2:37 am     Reply with quote

Hi,

I was facing the same issue with this accelerometer of getting 255 always. I had goofed up the SPI frequency to be given to the accelerometer.
Make sure SCLK is 8Mhz and Vdd is 3.3v

I am facing a weird problem now, I am able to read data however I am unable to write data.
Some of the posts helped. Let me see whether if I give delay after write it will help. I will post back if I am still facing the issue.

Dead line in 3 days and I am yet to write into a register, wuph.....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 12, 2010 2:26 pm     Reply with quote

Then post a compilable test program that demonstrates the failure.
balajivenu



Joined: 12 May 2010
Posts: 2
Location: India

View user's profile Send private message Send e-mail Visit poster's website

its working
PostPosted: Thu May 13, 2010 9:51 am     Reply with quote

well the write is happening now.
Next task is to interface the LCD to the micro...
i am facing a similar problem there, got to check where i have goofed up.
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