Lluis Nadal
/
MMA7455L_I2C_Test
MMA7455L test for I2C interface. 10-bit 8g mode.
main.cpp@0:17e709908189, 2011-08-21 (annotated)
- Committer:
- lnadal
- Date:
- Sun Aug 21 10:44:59 2011 +0000
- Revision:
- 0:17e709908189
Who changed what in which revision?
User | Revision | Line number | New 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 | } |