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 support@ccsinfo.com

MMA8453Q accelerometer routines

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
guy



Joined: 21 Oct 2005
Posts: 291

View user's profile Send private message Visit poster's website

MMA8453Q accelerometer routines
PostPosted: Sat Jul 04, 2015 2:58 am     Reply with quote

Here is code to set up and get readings from the MMA8453Q 3-axis accelerometer from Freescale (nice chip!)
It should give you a push in the right direction if you plan to use this part.
I also set up two interrupt lines from the chip to the MCU. Ack errors are not handled.


Code:

// MMA8453Q acceletormeter routines & constants:

// hardware-specific declarations:
#define   ACCEL_SA0   PIN_B6   // accelerometer address bit (output)
#define   ACCEL_IRQ1   PIN_A2   // Input from MMA8453Q IRQ1
#define   TILT_IRQ      PIN_A2   // Input from MMA8453Q IRQ1

// global vars (send results to main program)
signed int16 acc_xyz[3];         // new samples from accelerometer

#define   ACCEL_I2C_ADDR   0x1C

// accel. internal registers:
#define   TRANS_CFG   0x1D
#define   TRANS_THS   0x1F
#define   TRANS_COUNT   0x20
#define   TRANS_SRC   0x1E   // read-only. Check interrupt source & clear int.
#define   CTRL_REG1   0x2A   // setup, standby
#define   CTRL_REG4   0x2D   // interrupt enable
#define   CTRL_REG5   0x2E   // interrupt routing etc.

//////////////////////////////////////////

void AccelWrite(byte a,d) {
   // send register address & data over I2C
   short ack;   // 0=ACK 1=NAK

   I2C_Start();
   ack=I2C_Write(ACCEL_I2C_ADDR<<1);   // address+Write
   ack|=I2C_Write(a);
   ack|=I2C_Write(d);
   I2C_Stop();
}

///////////////   

byte AccelRead(byte a) {
   byte i;
   short ack;   // 0=ACK 1=NAK
   
   I2C_Start();
   ack=I2C_Write((ACCEL_I2C_ADDR<<1));   // address+Write
   ack|=I2C_Write(a);
   I2C_Start();                  // I2C restart
   ack|=I2C_Write((ACCEL_I2C_ADDR<<1)|1);// address+Read
   i=I2C_Read(0);
   I2C_Stop();
   return(i);
}

///////////////   


void init_accel() {
//   byte i;
   
//   SETUP ACCELEROMETER:
   output_low(ACCEL_SA0);      // bit0 of slave address = 0
   
//Step 1: Put the device in Standby Mode: Register 0x2A CTRL_REG1
   AccelWrite(CTRL_REG1,0x10);   //Set device in 200 Hz ODR, Standby, Slow read for 10-bit XYZ data
// test:   i=AccelRead(0x0D);
//Step 2: Enable X,Y,Z Axes and enable the latch: Register 0x1D Configuration Register
   AccelWrite(TRANS_CFG,0x1E);   //transient detect on X,Y,Z with latch
//Step 3: Set the Threshold: Register 0x1F
//Note: Step count is 0.063g per count
   AccelWrite(TRANS_THS,HIT_SENS);   //transient detect threshold set to 96 counts (6.048g)
//Step 4: Set the Debounce Counter: Register 0x20
   AccelWrite(TRANS_COUNT,4);   //debounce 20ms with ODR=200Hz,Normal->time step=5ms,20ms minimum detection time
//Step 5: Enable Transient Detection Interrupt in the System (CTRL_REG4)
   AccelWrite(CTRL_REG4,0x20);   //transient interrupt enable
//Step 6: Route the Transient Interrupt to INT 1 hardware pin (CTRL_REG5)
   AccelWrite(CTRL_REG5,0x20);   //transient interrupt on IRQ1
//Step 7: Put the device in Active Mode: Register 0x2A CTRL_REG1
//!!   i=AccelRead(CTRL_REG1);      //Read out the contents of the register
//!!   i|= 0x01;                //Change the value in the register to Active Mode.
//!!   AccelWrite(CTRL_REG1,i);   //Write in the updated value to put the device in Active Mode
   AccelWrite(CTRL_REG1,0x11);   //Write in the updated value to put the device in Active Mode

}

///////////////   

void updateXYZ() {
   // read XYZ data from accelerometer and update <acc_xyz> array
   
   byte i,h,l;
   int16 t;
   short ack;   // 0=ACK 1=NAK
   
   // use multiple byte read:
   I2C_Start();
   ack=I2C_Write((ACCEL_I2C_ADDR<<1));   // address+Write
   ack|=I2C_Write(0x01);            // OUT_X_MSB, first read address
   I2C_Start();                  // I2C restart
   ack|=I2C_Write((ACCEL_I2C_ADDR<<1)|1);// address+Read
   // 10-bit data :
   for(i=0;i<3;i++) {
      h=I2C_Read(1);
      l=I2C_Read(1);
      t=(make16(h,l))>>6;
      if(h&0x80) t|=0xFC00;         // if negative pad with 1's
      acc_xyz[i]=t;
   }
   h=I2C_Read(0);               // last read
   I2C_Stop();
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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