Lluis Nadal
/
MMA7455L_I2C_Test
MMA7455L test for I2C interface. 10-bit 8g mode.
main.cpp
- Committer:
- lnadal
- Date:
- 2011-08-21
- Revision:
- 0:17e709908189
File content as of revision 0:17e709908189:
#include "mbed.h" /* ************************************************************************************************* MMA7455. Simple test for I2C interface and 10-bit 8g mode . 2g, 4g, 8g, digital triple axis accelerometer with I2C/SPI interface. In Level Detection Mode and pulse detection mode, dynamic range is set automatically to 8g. Read or Write Low Byte first. Wiring: pin 2, pin 3, pin 5, IADDR0(pin 4), pin 10 and pin 11 tied to ground. DVdd(pin 1),AVdd(pin 6) and CS(pin 7) tied to 3.3V. INT1(p8) to mBed's p15(INT1 is not used in this program). INT2(p9) to mBed's p16. Author: Lluis Nadal. August 2011. ************************************************************************************************* */ I2C i2c(p9, p10); // SDA(p13), SCL(p14). 4.7k pull-up resistors. //pin 4 (IADDR0) tied to ground. const int addr_R = 0x3B; // Address to read: 111011 const int addr_W = 0x3A; // Address to write: 111010 Serial pc(USBTX, USBRX); DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); InterruptIn int1(p15); // InterruptIn int2(p16); // int offset[3]; int v[6]; int a; char msb, lsb; void read_8(int n) { // Read 8-bit register i2c.start(); v[0]=i2c.write(addr_W); v[1]=i2c.write(n); i2c.start(); v[2] = i2c.write(addr_R); v[3]=i2c.read(0); i2c.stop(); //ACK = v[0]= v[1]= v[2]= 1; NACK = 0. v[3] = value. pc.printf(" (v[0],v[1],v[2],v[3]) = (%d, %d, %d, %d)\r\n\r\n", v[0],v[1],v[2],v[3]); } void read(int n) { // Read 10-bit registers n and n+1 i2c.start(); i2c.write(addr_W); i2c.write(n); // Starting register(L) i2c.start(); i2c.write(addr_R); lsb = i2c.read(0); i2c.stop(); i2c.start(); i2c.write(addr_W); i2c.write(n+1); // Next register(H) i2c.start(); i2c.write(addr_R); msb = i2c.read(0); i2c.stop(); pc.printf(" (msb, lsb): (%d, %d)\r\n", msb, lsb); pc.printf("\r\n"); a = (int)msb; a = (a << 8) | lsb; if ((msb >> 1) == 1) a = a -1024; // If negative pc.printf(" a = %d\r\n\r\n", a); } void write_8(int reg, int data) { // Write 8-bit data to register i2c.start(); v[0]=i2c.write(addr_W); v[1]=i2c.write(reg); v[2] = i2c.write(data); i2c.stop(); //ACK = v[0]= v[1]= v[2] = 1; NACK = 0. // pc.printf(" (v[0],v[1],v[2]) = (%d, %d, %d)\r\n", v[0],v[1],v[2]); // pc.printf("\r\n"); } void write_offset(int reg, int data) { // Write 11-bit data to offset registers L and H char H, L; i2c.start(); i2c.write(addr_W); i2c.write(reg); // Starting register(L) if (data < 0) data = 2048 + data ; // If negative pc.printf(" data = %d\r\n", data); H = (char) ((data & 0xFF00) >> 8); L = (char) (data & 0x00FF); i2c.write(L); i2c.stop(); i2c.start(); i2c.write(addr_W); i2c.write(reg+1); // Next register(H) i2c.write(H); i2c.stop(); pc.printf(" (H, L) = (%d, %d )\r\n\r\n", H, L); } void clr_int() { // Clear interrupt latch write_8(0x17, 0x03); write_8(0x17, 0x00); // Default option } void flash() { led4 = 0; pc.printf("Pulse detected!\r\n"); led4 = 1; wait(1); led4 = 0; clr_int(); // Clear interrupt latch } int main() { i2c.frequency(100000); led1 = 0, led2 = 0, led3 = 0, led4 = 0; wait(2); // Read some 8-bit registers pc.printf(" Read some registers: \r\n\r\n"); pc.printf(" WHOAMI register: "); read_8(0x0F); // WHOAMI pc.printf(" I2C ADDRESS: "); read_8(0x0D); // I2C ADDRESS pc.printf(" MODE CONTROL register: "); read_8(0x16); // Mode control register // 0x16: Mode[1:0] Control Register: // 00: Standby Mode // 01: Measurement Mode // 10: Level Detection Mode // 11: Pulse Detection Mode // 0x16: GLV[1:0] Control Register: // 00: 8g // 10: 4g // 01: 2g pc.printf( "Write to MODE CONTROL register 0x16\r\n\r\n"); // Write: DRPD = 1, GLVL = 00(8g), MODE: 01(Measurement). write_8(0x16, 0x41); clr_int(); // Clear interrupt latch pc.printf(" MODE CONTROL register updated: "); read_8(0x16); // MODE CONTROL register is updated pc.printf(" Interrupt latch register: "); read_8(0x17); // Interrupt latch register pc.printf(" Status: "); read_8(0x09); // Status // Clear offset registers: 11-bit pc.printf(" Clear offset registers\r\n\r\n"); write_offset(0x10, 0); // Offset x write_offset(0x12, 0); // Offset y write_offset(0x14, 0); // Offset z wait(0.1); // Start autocalibration. Lay device down horizontal and do not move // Average 4 readings // Offsets must be multiplied by 2 pc.printf(" Autocalibration: lay device down horizontal and do not move\r\n\r\n"); led1 = 1; // Start autocalibration in 4 seconds wait(4); offset[0] = 0, offset[1] = 0, offset[2] = 0; for (int i = 0; i < 4; i++) { pc.printf(" x: \r\n"); read(0x00); offset[0] = offset[0]-a; pc.printf( "y: \r\n"); read(0x02); offset[1] = offset[1]-a ; pc.printf(" z: \r\n"); read(0x04); offset[2] = offset[2]-a; wait(0.2); } led2 = 1; // End autocalibration // Offsets must be multiplied by 2 and divided by 4 to calculate the average offset[0] = offset[0]/2; offset[1] = offset[1]/2; offset[2] = offset[2]/2 + 2*64; //Z axis output for 1g must be 64 in 10-bit mode // Write offset registers (11-bit). Offset registers are volatile and are cleared on power off. pc.printf(" Write offset registers\r\n\r\n"); write_offset(0x10, offset[0]); // Offset x write_offset(0x12, offset[1]); // Offset y write_offset(0x14, offset[2]); // Offset z wait(0.1); // Read x, y, z with offset correction pc.printf(" Read x, y, z with offset correction\r\n\r\n"); pc.printf(" x corrected: \r\n"); read(0x00); pc.printf( "y corrected: \r\n"); read(0x02); pc.printf(" z corrected: \r\n"); read(0x04); wait(0.1); // Single pulse detection write_8(0x16, 0x43); // DRPD = 1; GLV = 00(8g), MODE: 11(pulse detection). write_8(0x19, 0x00); write_8(0x18, 0x00); // Int2 for pulse detection write_8(0x1B, 0x20); // Unsigned 7-bit Pulse Treshold set to 2g. write_8(0x1C, 0x10); // Pulse duration set to 8 ms int2.rise(&flash); // Attach flash function to int2 pc.printf(" Start pulse detection\r\n\r\n"); led3 = 1; // Start pulse detection while (1) { } }