arduino中用IIC读取MMA8452三轴加速度模块数据

  1. http://www.geek-workshop.com/thread-898-1-1.html
  2. /*
  3. MMA8452Q Basic Example Code
  4. Nathan Seidle
  5. SparkFun Electronics
  6. November 5, 2012

  7. License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

  8. This example code shows how to read the X/Y/Z accelerations and basic functions of the MMA5842. It leaves out
  9. all the neat features this IC is capable of (tap, orientation, and inerrupts) and just displays X/Y/Z. See
  10. the advanced example code to see more features.

  11. Hardware setup:
  12. MMA8452 Breakout ------------ Arduino
  13. 3.3V --------------------- 3.3V
  14. SDA -------^^(330)^^------- A4
  15. SCL -------^^(330)^^------- A5
  16. GND ---------------------- GND

  17. The MMA8452 is 3.3V so we recommend using 330 or 1k resistors between a 5V Arduino and the MMA8452 breakout.

  18. The MMA8452 has built in pull-up resistors for I2C so you do not need additional pull-ups.
  19. */

  20. #include <Wire.h> // Used for I2C

  21. // The SparkFun breakout board defaults to 1, set to 0 if SA0 jumper on the bottom of the board is set
  22. #define MMA8452_ADDRESS 0x1D  // 0x1D if SA0 is high, 0x1C if low

  23. //Define a few of the registers that we will be accessing on the MMA8452
  24. #define OUT_X_MSB 0x01
  25. #define XYZ_DATA_CFG  0x0E
  26. #define WHO_AM_I   0x0D
  27. #define CTRL_REG1  0x2A

  28. #define GSCALE 2 // Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values.

  29. void setup()
  30. {
  31.   Serial.begin(9600);
  32.   Serial.println("MMA8452 Basic Example");

  33.   Wire.begin(); //Join the bus as a master

  34.   initMMA8452(); //Test and intialize the MMA8452
  35. }

  36. void loop()
  37. {  
  38.   int accelCount[3];  // Stores the 12-bit signed value
  39.   readAccelData(accelCount);  // Read the x/y/z adc values

  40.   // Now we'll calculate the accleration value into actual g's
  41.   float accelG[3];  // Stores the real accel value in g's
  42.   for (int i = 0 ; i < 3 ; i++)
  43.   {
  44.     accelG[i] = (float) accelCount[i] / ((1<<12)/(2*GSCALE));  // get actual g value, this depends on scale being set
  45.   }

  46.   // Print out values
  47.   for (int i = 0 ; i < 3 ; i++)
  48.   {
  49.     Serial.print(accelG[i], 4);  // Print g values
  50.     Serial.print("\t");  // tabs in between axes
  51.   }
  52.   Serial.println();

  53.   delay(10);  // Delay here for visibility
  54. }

  55. void readAccelData(int *destination)
  56. {
  57.   byte rawData[6];  // x/y/z accel register data stored here

  58.   readRegisters(OUT_X_MSB, 6, rawData);  // Read the six raw data registers into data array

  59.   // Loop to calculate 12-bit ADC and g value for each axis
  60.   for(int i = 0; i < 3 ; i++)
  61.   {
  62.     int gCount = (rawData[i*2] << 8) | rawData[(i*2)+1];  //Combine the two 8 bit registers into one 12-bit number
  63.     gCount >>= 4; //The registers are left align, here we right align the 12-bit integer

  64.     // If the number is negative, we have to make it so manually (no 12-bit data type)
  65.     if (rawData[i*2] > 0x7F)
  66.     {  
  67.       gCount = ~gCount + 1;
  68.       gCount *= -1;  // Transform into negative 2's complement #
  69.     }

  70.     destination[i] = gCount; //Record this gCount into the 3 int array
  71.   }
  72. }

  73. // Initialize the MMA8452 registers
  74. // See the many application notes for more info on setting all of these registers:
  75. // http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA8452Q
  76. void initMMA8452()
  77. {
  78.   byte c = readRegister(WHO_AM_I);  // Read WHO_AM_I register
  79.   if (c == 0x2A) // WHO_AM_I should always be 0x2A
  80.   {  
  81.     Serial.println("MMA8452Q is online...");
  82.   }
  83.   else
  84.   {
  85.     Serial.print("Could not connect to MMA8452Q: 0x");
  86.     Serial.println(c, HEX);
  87.     while(1) ; // Loop forever if communication doesn't happen
  88.   }

  89.   MMA8452Standby();  // Must be in standby to change registers

  90.   // Set up the full scale range to 2, 4, or 8g.
  91.   byte fsr = GSCALE;
  92.   if(fsr > 8) fsr = 8; //Easy error check
  93.   fsr >>= 2; // Neat trick, see page 22. 00 = 2G, 01 = 4A, 10 = 8G
  94.   writeRegister(XYZ_DATA_CFG, fsr);

  95.   //The default data rate is 800Hz and we don't modify it in this example code

  96.   MMA8452Active();  // Set to active to start reading
  97. }

  98. // Sets the MMA8452 to standby mode. It must be in standby to change most register settings
  99. void MMA8452Standby()
  100. {
  101.   byte c = readRegister(CTRL_REG1);
  102.   writeRegister(CTRL_REG1, c & ~(0x01)); //Clear the active bit to go into standby
  103. }

  104. // Sets the MMA8452 to active mode. Needs to be in this mode to output data
  105. void MMA8452Active()
  106. {
  107.   byte c = readRegister(CTRL_REG1);
  108.   writeRegister(CTRL_REG1, c | 0x01); //Set the active bit to begin detection
  109. }

  110. // Read bytesToRead sequentially, starting at addressToRead into the dest byte array
  111. void readRegisters(byte addressToRead, int bytesToRead, byte * dest)
  112. {
  113.   Wire.beginTransmission(MMA8452_ADDRESS);
  114.   Wire.write(addressToRead);
  115.   Wire.endTransmission(false); //endTransmission but keep the connection active

  116.   Wire.requestFrom(MMA8452_ADDRESS, bytesToRead); //Ask for bytes, once done, bus is released by default

  117.   while(Wire.available() < bytesToRead); //Hang out until we get the # of bytes we expect

  118.   for(int x = 0 ; x < bytesToRead ; x++)
  119.     dest[x] = Wire.read();   
  120. }

  121. // Read a single byte from addressToRead and return it as a byte
  122. byte readRegister(byte addressToRead)
  123. {
  124.   Wire.beginTransmission(MMA8452_ADDRESS);
  125.   Wire.write(addressToRead);
  126.   Wire.endTransmission(false); //endTransmission but keep the connection active

  127.   Wire.requestFrom(MMA8452_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by default

  128.   while(!Wire.available()) ; //Wait for the data to come back
  129.   return Wire.read(); //Return this one byte
  130. }

  131. // Writes a single byte (dataToWrite) into addressToWrite
  132. void writeRegister(byte addressToWrite, byte dataToWrite)
  133. {
  134.   Wire.beginTransmission(MMA8452_ADDRESS);
  135.   Wire.write(addressToWrite);
  136.   Wire.write(dataToWrite);
  137.   Wire.endTransmission(); //Stop transmitting
  138. }

你可能感兴趣的:(arduino中用IIC读取MMA8452三轴加速度模块数据)