Read a Freescale MMA7455 Accelerometer using I2C

Download pre-release library modules and new examples to use with Astrobe for Cortex-M. Forum members can also upload their own source code examples.
Post Reply
cfbsoftware
Site Admin
Posts: 493
Joined: Fri Dec 31, 2010 12:30 pm
Contact:

Read a Freescale MMA7455 Accelerometer using I2C

Post by cfbsoftware » Sat Jun 09, 2012 1:06 am

Code: Select all

MODULE Accelerometer;
(* =========================================================================  
   Example Cortex-M3 Oberon I2C Accelerometer Program  

   Description:
     Reads the accelerometer X, Y, Z and temperature values every 50ms and 
     displays the values whenever the change exceeds a specified threshold. 
   
   Target: 
     LPC13xx systems with a Freescale MMA7455 3-axis Accelerometer 
     connected to the I2C bus

   Tested with:
     Embedded Artists LPC1343 LPCXpresso + baseboard  
     
   Refs: 
     NXP LPC13xx User Manual UM10375
     Freescale MMA7455 Datasheet
     Oberon for Cortex-M3 Microcontrollers
   
   (c) 2010-2012 CFB Software   
   http://www.astrobe.com  
   
   ========================================================================= *)

IMPORT MCU, I2C, SYSTEM, Main, Out, Timer;

PROCEDURE SetMode(addr, mode, sensitivity: INTEGER);
VAR
  cmd, data: CHAR;
  status: INTEGER;
BEGIN
  ASSERT(sensitivity IN {0..2}, 100);
  ASSERT(mode IN {0..2}, 101);
  (* Mode control *)
  cmd := 016X;
  data := CHR(LSL(sensitivity, 2) + mode);
  status := I2C.WriteBytes(addr, cmd, 1, data, 0, 1);
  ASSERT(status = I2C.OK, 102)
END SetMode;


PROCEDURE* Diff(prev, this: INTEGER): INTEGER;
  RETURN ABS(prev - this)
END Diff;


PROCEDURE OutData(label: ARRAY OF CHAR; data: INTEGER);
BEGIN
  Out.String(label); Out.Int(data, 5)
END OutData;


PROCEDURE Data(addr: INTEGER; cmd: CHAR): INTEGER;
VAR
  data, status: INTEGER;
BEGIN
  data := 0;
  status := I2C.ReadBytes(addr, cmd, 1, data, 0, 1);
  ASSERT(status = I2C.OK, 103);
  IF (data >= 128) THEN data := data - 256 END; 
  RETURN data
END Data;
  

PROCEDURE Run();
CONST
  I2CFreq = 400000;
  I2CBus = 0;
  range2g = 1;
  measurementMode = 1;
  MMA7455Addr = 01DH;
  (* Minimum change to be reported *)
  Threshold = 3;
  (* 8-bit signed integer *)
  MaxXYZ = 127;
VAR
  thisX, thisY, thisZ, prevX, prevY, prevZ: INTEGER;
  xAddr, yAddr, zAddr: CHAR;
BEGIN
  I2C.Init(I2CBus, I2CFreq);
  SetMode(MMA7455Addr, measurementMode, range2g);
  
  xAddr := 06X;
  yAddr := 07X;
  zAddr := 08X;
  prevX := MaxXYZ + Threshold + 1; 
  prevY := MaxXYZ + Threshold + 1; 
  prevZ := MaxXYZ + Threshold + 1;
  
  WHILE TRUE DO 
    thisX := Data(MMA7455Addr, xAddr); 
    thisY := Data(MMA7455Addr, yAddr); 
    thisZ := Data(MMA7455Addr, zAddr); 
    
    (* Check if the change is enough to be reported *)
    IF (Diff(prevX, thisX) > Threshold)
    OR (Diff(prevY, thisY) > Threshold)
    OR (Diff(prevZ, thisZ) > Threshold) THEN 
      OutData("x:", thisX); 
      OutData(", y:", thisY); 
      OutData(", z:", thisZ); 
      Out.Ln();
      prevX := thisX; prevY := thisY; prevZ := thisZ;
    END;
    
    Timer.MSecDelay(50)
  END
END Run;


BEGIN
  Run()
END Accelerometer.
Attachments
Accelerometer.zip
Accelerometer.mod
(1.29 KiB) Downloaded 1049 times

Post Reply