PIC16f887 with MMA7455 accelerometer, I2C problem

Thread Starter

andrei_w

Joined Jun 6, 2010
9
Hi, I am trying get results with I2C from a MMA7455 accelerometer but i'm stuck. I use MikroC Pro and his library. I have connected the CS pin to VCC, SDA to RC4, SCL to RC3, VCC to VCC and GND to GND. First I want to read the values from the x axis. If the value it would be bigger then "0" i should have a led turned on, else the led should be turned off. I have read the datasheet and I have understood that the address of MMA7455 is 0x0D (please correct me if i'm wrong), and the register of X axis is 0x06( i have tried also 0x00). Because it didn't worked like this i have searched the web and I have found different addreses for the same accelerometer. Some people said that te address is 0x3A or 0x2D, i tried these addresses but it didn't work. Please help me. Here it is the code

Rich (BB code):
// Software I2C connections
sbit Soft_I2C_Scl           at RC3_bit;
sbit Soft_I2C_Sda           at RC4_bit;
sbit Soft_I2C_Scl_Direction at TRISC3_bit;
sbit Soft_I2C_Sda_Direction at TRISC4_bit;
// End Software I2C connections

char X;

void Read_X() {

  Soft_I2C_Start();               // Issue start signal
  Soft_I2C_Write(0x3A);          
  Soft_I2C_Write(0x00);              
  Soft_I2C_Start();               // Issue repeated start signal
  Soft_I2C_Write(0x3B);         
  X = Soft_I2C_Read(0u);     
  Soft_I2C_Stop();
}

void Init_Main() {

  ANSEL  = 0;                // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;              // Disable comparators
  C2ON_bit = 0;
  Soft_I2C_Init();           // Initialize Soft I2C communication

}


void main() {                // Main procedure
  Delay_ms(500);
  Init_Main();               // Perform initialization

  while (1) {
    Read_X();
      if (X<0)    
      {  trisb.b5=0;
         portb.b5=1;}
  else              
      {  trisb.b5=1;
         portb.b5=0;}
  }
}
 

SgtWookie

Joined Jul 17, 2007
22,230
Excerpt from page 16 in the datasheet:

I2C Slave Interface
I2C is a synchronous serial communication between a master device and one or more slave devices. The master is typically a
microcontroller, which provides the serial clock signal and addresses the slave device(s) on the bus. The MMA7455L communicates only in slave operation where the device address is $1D.
A datasheet:
http://strawberry-linux.com/pub/MMA7455L.pdf
 

thatoneguy

Joined Feb 19, 2009
6,359
@thatoneguy, how do you put a PICKit 2 (or 3) into logic record mode?
When it is plugged in, open the PICKit 2 standalone program, click on "Tools", then "Logic Tool" or "UART Debugger".

There is a standalone program for the PICKit 3, but it only supports programming, no probing or logic injection.
 

russpatterson

Joined Feb 1, 2010
353
@Andrew,

FWIW here's what I have done to find/fix digital communication issues:

1) You need to be able to verify that you are sending and receiving is the right stuff. If you don't have access to a logic analyzer, I would recommend finding one. They sell a decent USB Logic analyzer, and one analog channel, at SparkFun.com. You could use a scope in a pinch as well. One way or another you need to be able to see what your sending and what is coming back. Read the data sheet and understand exactly what clock and data should look like. Draw the expected clock and data patterns on a piece of paper so you really understand what you're trying to get to happen.

2) If step one looks good then try another I2C device that you know works and verify your code still makes that work. Sparkfun sells tons of breakout boards that talk I2C, & SPI. Use something like that to verify the rest of your setup. If that part works but not response from your new part then maybe the part got damaged and swap it out.

There's only so far you can go with this stuff without some test gear.
 

ErnieM

Joined Apr 24, 2011
8,377
Your addresses for the device are fine. 0x3A is correct to write, 0x3B correct for read per the data sheet SgtWookie linked us to. That is the device I2C address, you must also talk to the registers inside.

Register 0x00 is the LSB of the X value, read again should increment to address 0x01 to read the higher 2 bits.

I do not see any register initiation, though it is possible none is required.

I do not see you calling Soft_I2C_Init(); to turn the soft interface on. That should set the TRIS bits and the initial state.

I2C is a static interface. meaning you can go as slow as you want. You can debug it with a voltmeter by sending the device address over 8 clocks and see if the 9th clock is hi or low (low means ACK and the slave is saying HI).
 

thatoneguy

Joined Feb 19, 2009
6,359
I do not see any register initiation, though it is possible none is required.
I do not see you calling Soft_I2C_Init(); to turn the soft interface on. That should set the TRIS bits and the initial state.
It is called from main_Init(), which is called 1/2 second into the main loop.


I2C is a static interface. meaning you can go as slow as you want. You can debug it with a voltmeter by sending the device address over 8 clocks and see if the 9th clock is hi or low (low means ACK and the slave is saying HI).
This is a workable idea, as well.
 

Thread Starter

andrei_w

Joined Jun 6, 2010
9
I have used this code with TPA81 sensor and it's working well. The signals on the oscilloscope are ok. I think the hardware it might be broken or this accelerometer have some special settings and i didn't make them. I will buy another accelerometer
 
Top