MMA7455L test for I2C interface. 10-bit 8g mode.

Dependencies:   mbed

Committer:
lnadal
Date:
Sun Aug 21 10:44:59 2011 +0000
Revision:
0:17e709908189

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lnadal 0:17e709908189 1 #include "mbed.h"
lnadal 0:17e709908189 2
lnadal 0:17e709908189 3 /*
lnadal 0:17e709908189 4 *************************************************************************************************
lnadal 0:17e709908189 5 MMA7455. Simple test for I2C interface and 10-bit 8g mode . 2g, 4g, 8g, digital triple axis accelerometer
lnadal 0:17e709908189 6 with I2C/SPI interface.
lnadal 0:17e709908189 7
lnadal 0:17e709908189 8 In Level Detection Mode and pulse detection mode, dynamic range is set automatically to 8g.
lnadal 0:17e709908189 9 Read or Write Low Byte first.
lnadal 0:17e709908189 10
lnadal 0:17e709908189 11 Wiring:
lnadal 0:17e709908189 12 pin 2, pin 3, pin 5, IADDR0(pin 4), pin 10 and pin 11 tied to ground.
lnadal 0:17e709908189 13 DVdd(pin 1),AVdd(pin 6) and CS(pin 7) tied to 3.3V.
lnadal 0:17e709908189 14 INT1(p8) to mBed's p15(INT1 is not used in this program). INT2(p9) to mBed's p16.
lnadal 0:17e709908189 15
lnadal 0:17e709908189 16 Author: Lluis Nadal. August 2011.
lnadal 0:17e709908189 17 *************************************************************************************************
lnadal 0:17e709908189 18 */
lnadal 0:17e709908189 19
lnadal 0:17e709908189 20 I2C i2c(p9, p10); // SDA(p13), SCL(p14). 4.7k pull-up resistors.
lnadal 0:17e709908189 21
lnadal 0:17e709908189 22 //pin 4 (IADDR0) tied to ground.
lnadal 0:17e709908189 23 const int addr_R = 0x3B; // Address to read: 111011
lnadal 0:17e709908189 24 const int addr_W = 0x3A; // Address to write: 111010
lnadal 0:17e709908189 25
lnadal 0:17e709908189 26 Serial pc(USBTX, USBRX);
lnadal 0:17e709908189 27
lnadal 0:17e709908189 28 DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
lnadal 0:17e709908189 29 InterruptIn int1(p15); //
lnadal 0:17e709908189 30 InterruptIn int2(p16); //
lnadal 0:17e709908189 31
lnadal 0:17e709908189 32 int offset[3];
lnadal 0:17e709908189 33 int v[6];
lnadal 0:17e709908189 34 int a;
lnadal 0:17e709908189 35 char msb, lsb;
lnadal 0:17e709908189 36
lnadal 0:17e709908189 37
lnadal 0:17e709908189 38
lnadal 0:17e709908189 39
lnadal 0:17e709908189 40 void read_8(int n) { // Read 8-bit register
lnadal 0:17e709908189 41 i2c.start();
lnadal 0:17e709908189 42 v[0]=i2c.write(addr_W);
lnadal 0:17e709908189 43 v[1]=i2c.write(n);
lnadal 0:17e709908189 44 i2c.start();
lnadal 0:17e709908189 45 v[2] = i2c.write(addr_R);
lnadal 0:17e709908189 46 v[3]=i2c.read(0);
lnadal 0:17e709908189 47 i2c.stop();
lnadal 0:17e709908189 48 //ACK = v[0]= v[1]= v[2]= 1; NACK = 0. v[3] = value.
lnadal 0:17e709908189 49 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]);
lnadal 0:17e709908189 50 }
lnadal 0:17e709908189 51
lnadal 0:17e709908189 52
lnadal 0:17e709908189 53 void read(int n) { // Read 10-bit registers n and n+1
lnadal 0:17e709908189 54 i2c.start();
lnadal 0:17e709908189 55 i2c.write(addr_W);
lnadal 0:17e709908189 56 i2c.write(n); // Starting register(L)
lnadal 0:17e709908189 57 i2c.start();
lnadal 0:17e709908189 58 i2c.write(addr_R);
lnadal 0:17e709908189 59 lsb = i2c.read(0);
lnadal 0:17e709908189 60 i2c.stop();
lnadal 0:17e709908189 61
lnadal 0:17e709908189 62 i2c.start();
lnadal 0:17e709908189 63 i2c.write(addr_W);
lnadal 0:17e709908189 64 i2c.write(n+1); // Next register(H)
lnadal 0:17e709908189 65 i2c.start();
lnadal 0:17e709908189 66 i2c.write(addr_R);
lnadal 0:17e709908189 67 msb = i2c.read(0);
lnadal 0:17e709908189 68 i2c.stop();
lnadal 0:17e709908189 69 pc.printf(" (msb, lsb): (%d, %d)\r\n", msb, lsb);
lnadal 0:17e709908189 70 pc.printf("\r\n");
lnadal 0:17e709908189 71 a = (int)msb;
lnadal 0:17e709908189 72 a = (a << 8) | lsb;
lnadal 0:17e709908189 73 if ((msb >> 1) == 1) a = a -1024; // If negative
lnadal 0:17e709908189 74 pc.printf(" a = %d\r\n\r\n", a);
lnadal 0:17e709908189 75 }
lnadal 0:17e709908189 76
lnadal 0:17e709908189 77
lnadal 0:17e709908189 78 void write_8(int reg, int data) { // Write 8-bit data to register
lnadal 0:17e709908189 79 i2c.start();
lnadal 0:17e709908189 80 v[0]=i2c.write(addr_W);
lnadal 0:17e709908189 81 v[1]=i2c.write(reg);
lnadal 0:17e709908189 82 v[2] = i2c.write(data);
lnadal 0:17e709908189 83 i2c.stop();
lnadal 0:17e709908189 84 //ACK = v[0]= v[1]= v[2] = 1; NACK = 0.
lnadal 0:17e709908189 85 // pc.printf(" (v[0],v[1],v[2]) = (%d, %d, %d)\r\n", v[0],v[1],v[2]);
lnadal 0:17e709908189 86 // pc.printf("\r\n");
lnadal 0:17e709908189 87 }
lnadal 0:17e709908189 88
lnadal 0:17e709908189 89 void write_offset(int reg, int data) { // Write 11-bit data to offset registers L and H
lnadal 0:17e709908189 90 char H, L;
lnadal 0:17e709908189 91 i2c.start();
lnadal 0:17e709908189 92 i2c.write(addr_W);
lnadal 0:17e709908189 93 i2c.write(reg); // Starting register(L)
lnadal 0:17e709908189 94 if (data < 0) data = 2048 + data ; // If negative
lnadal 0:17e709908189 95 pc.printf(" data = %d\r\n", data);
lnadal 0:17e709908189 96 H = (char) ((data & 0xFF00) >> 8);
lnadal 0:17e709908189 97 L = (char) (data & 0x00FF);
lnadal 0:17e709908189 98 i2c.write(L);
lnadal 0:17e709908189 99 i2c.stop();
lnadal 0:17e709908189 100 i2c.start();
lnadal 0:17e709908189 101 i2c.write(addr_W);
lnadal 0:17e709908189 102 i2c.write(reg+1); // Next register(H)
lnadal 0:17e709908189 103 i2c.write(H);
lnadal 0:17e709908189 104 i2c.stop();
lnadal 0:17e709908189 105 pc.printf(" (H, L) = (%d, %d )\r\n\r\n", H, L);
lnadal 0:17e709908189 106 }
lnadal 0:17e709908189 107
lnadal 0:17e709908189 108
lnadal 0:17e709908189 109
lnadal 0:17e709908189 110
lnadal 0:17e709908189 111 void clr_int() { // Clear interrupt latch
lnadal 0:17e709908189 112 write_8(0x17, 0x03);
lnadal 0:17e709908189 113 write_8(0x17, 0x00); // Default option
lnadal 0:17e709908189 114 }
lnadal 0:17e709908189 115
lnadal 0:17e709908189 116 void flash() {
lnadal 0:17e709908189 117 led4 = 0;
lnadal 0:17e709908189 118 pc.printf("Pulse detected!\r\n");
lnadal 0:17e709908189 119 led4 = 1;
lnadal 0:17e709908189 120 wait(1);
lnadal 0:17e709908189 121 led4 = 0;
lnadal 0:17e709908189 122 clr_int(); // Clear interrupt latch
lnadal 0:17e709908189 123 }
lnadal 0:17e709908189 124
lnadal 0:17e709908189 125
lnadal 0:17e709908189 126
lnadal 0:17e709908189 127
lnadal 0:17e709908189 128 int main() {
lnadal 0:17e709908189 129
lnadal 0:17e709908189 130 i2c.frequency(100000);
lnadal 0:17e709908189 131
lnadal 0:17e709908189 132 led1 = 0, led2 = 0, led3 = 0, led4 = 0;
lnadal 0:17e709908189 133 wait(2);
lnadal 0:17e709908189 134
lnadal 0:17e709908189 135 // Read some 8-bit registers
lnadal 0:17e709908189 136 pc.printf(" Read some registers: \r\n\r\n");
lnadal 0:17e709908189 137
lnadal 0:17e709908189 138
lnadal 0:17e709908189 139 pc.printf(" WHOAMI register: ");
lnadal 0:17e709908189 140 read_8(0x0F); // WHOAMI
lnadal 0:17e709908189 141
lnadal 0:17e709908189 142 pc.printf(" I2C ADDRESS: ");
lnadal 0:17e709908189 143 read_8(0x0D); // I2C ADDRESS
lnadal 0:17e709908189 144
lnadal 0:17e709908189 145 pc.printf(" MODE CONTROL register: ");
lnadal 0:17e709908189 146 read_8(0x16); // Mode control register
lnadal 0:17e709908189 147
lnadal 0:17e709908189 148
lnadal 0:17e709908189 149 // 0x16: Mode[1:0] Control Register:
lnadal 0:17e709908189 150 // 00: Standby Mode
lnadal 0:17e709908189 151 // 01: Measurement Mode
lnadal 0:17e709908189 152 // 10: Level Detection Mode
lnadal 0:17e709908189 153 // 11: Pulse Detection Mode
lnadal 0:17e709908189 154
lnadal 0:17e709908189 155 // 0x16: GLV[1:0] Control Register:
lnadal 0:17e709908189 156 // 00: 8g
lnadal 0:17e709908189 157 // 10: 4g
lnadal 0:17e709908189 158 // 01: 2g
lnadal 0:17e709908189 159
lnadal 0:17e709908189 160 pc.printf( "Write to MODE CONTROL register 0x16\r\n\r\n");
lnadal 0:17e709908189 161 // Write: DRPD = 1, GLVL = 00(8g), MODE: 01(Measurement).
lnadal 0:17e709908189 162 write_8(0x16, 0x41);
lnadal 0:17e709908189 163 clr_int(); // Clear interrupt latch
lnadal 0:17e709908189 164
lnadal 0:17e709908189 165 pc.printf(" MODE CONTROL register updated: ");
lnadal 0:17e709908189 166 read_8(0x16); // MODE CONTROL register is updated
lnadal 0:17e709908189 167
lnadal 0:17e709908189 168 pc.printf(" Interrupt latch register: ");
lnadal 0:17e709908189 169 read_8(0x17); // Interrupt latch register
lnadal 0:17e709908189 170
lnadal 0:17e709908189 171 pc.printf(" Status: ");
lnadal 0:17e709908189 172 read_8(0x09); // Status
lnadal 0:17e709908189 173
lnadal 0:17e709908189 174 // Clear offset registers: 11-bit
lnadal 0:17e709908189 175 pc.printf(" Clear offset registers\r\n\r\n");
lnadal 0:17e709908189 176 write_offset(0x10, 0); // Offset x
lnadal 0:17e709908189 177 write_offset(0x12, 0); // Offset y
lnadal 0:17e709908189 178 write_offset(0x14, 0); // Offset z
lnadal 0:17e709908189 179 wait(0.1);
lnadal 0:17e709908189 180
lnadal 0:17e709908189 181 // Start autocalibration. Lay device down horizontal and do not move
lnadal 0:17e709908189 182 // Average 4 readings
lnadal 0:17e709908189 183 // Offsets must be multiplied by 2
lnadal 0:17e709908189 184 pc.printf(" Autocalibration: lay device down horizontal and do not move\r\n\r\n");
lnadal 0:17e709908189 185 led1 = 1; // Start autocalibration in 4 seconds
lnadal 0:17e709908189 186 wait(4);
lnadal 0:17e709908189 187 offset[0] = 0, offset[1] = 0, offset[2] = 0;
lnadal 0:17e709908189 188
lnadal 0:17e709908189 189 for (int i = 0; i < 4; i++) {
lnadal 0:17e709908189 190
lnadal 0:17e709908189 191 pc.printf(" x: \r\n");
lnadal 0:17e709908189 192 read(0x00);
lnadal 0:17e709908189 193 offset[0] = offset[0]-a;
lnadal 0:17e709908189 194
lnadal 0:17e709908189 195 pc.printf( "y: \r\n");
lnadal 0:17e709908189 196 read(0x02);
lnadal 0:17e709908189 197 offset[1] = offset[1]-a ;
lnadal 0:17e709908189 198
lnadal 0:17e709908189 199 pc.printf(" z: \r\n");
lnadal 0:17e709908189 200 read(0x04);
lnadal 0:17e709908189 201 offset[2] = offset[2]-a;
lnadal 0:17e709908189 202 wait(0.2);
lnadal 0:17e709908189 203 }
lnadal 0:17e709908189 204
lnadal 0:17e709908189 205 led2 = 1; // End autocalibration
lnadal 0:17e709908189 206
lnadal 0:17e709908189 207 // Offsets must be multiplied by 2 and divided by 4 to calculate the average
lnadal 0:17e709908189 208 offset[0] = offset[0]/2;
lnadal 0:17e709908189 209 offset[1] = offset[1]/2;
lnadal 0:17e709908189 210 offset[2] = offset[2]/2 + 2*64; //Z axis output for 1g must be 64 in 10-bit mode
lnadal 0:17e709908189 211
lnadal 0:17e709908189 212
lnadal 0:17e709908189 213 // Write offset registers (11-bit). Offset registers are volatile and are cleared on power off.
lnadal 0:17e709908189 214 pc.printf(" Write offset registers\r\n\r\n");
lnadal 0:17e709908189 215 write_offset(0x10, offset[0]); // Offset x
lnadal 0:17e709908189 216 write_offset(0x12, offset[1]); // Offset y
lnadal 0:17e709908189 217 write_offset(0x14, offset[2]); // Offset z
lnadal 0:17e709908189 218 wait(0.1);
lnadal 0:17e709908189 219
lnadal 0:17e709908189 220
lnadal 0:17e709908189 221 // Read x, y, z with offset correction
lnadal 0:17e709908189 222 pc.printf(" Read x, y, z with offset correction\r\n\r\n");
lnadal 0:17e709908189 223 pc.printf(" x corrected: \r\n");
lnadal 0:17e709908189 224 read(0x00);
lnadal 0:17e709908189 225 pc.printf( "y corrected: \r\n");
lnadal 0:17e709908189 226 read(0x02);
lnadal 0:17e709908189 227 pc.printf(" z corrected: \r\n");
lnadal 0:17e709908189 228 read(0x04);
lnadal 0:17e709908189 229 wait(0.1);
lnadal 0:17e709908189 230
lnadal 0:17e709908189 231 // Single pulse detection
lnadal 0:17e709908189 232 write_8(0x16, 0x43); // DRPD = 1; GLV = 00(8g), MODE: 11(pulse detection).
lnadal 0:17e709908189 233 write_8(0x19, 0x00);
lnadal 0:17e709908189 234 write_8(0x18, 0x00); // Int2 for pulse detection
lnadal 0:17e709908189 235 write_8(0x1B, 0x20); // Unsigned 7-bit Pulse Treshold set to 2g.
lnadal 0:17e709908189 236 write_8(0x1C, 0x10); // Pulse duration set to 8 ms
lnadal 0:17e709908189 237 int2.rise(&flash); // Attach flash function to int2
lnadal 0:17e709908189 238 pc.printf(" Start pulse detection\r\n\r\n");
lnadal 0:17e709908189 239 led3 = 1; // Start pulse detection
lnadal 0:17e709908189 240
lnadal 0:17e709908189 241 while (1) {
lnadal 0:17e709908189 242 }
lnadal 0:17e709908189 243 }