簡體   English   中英

ADXL373 加速度計 SPI 通信問題

[英]ADXL373 Accelerometer SPI Communication Issue

作為序言,我是 Arduino 和電子通信的新手。 我正處於基於 Arduino 的加速度計設置的初始階段,以記錄撞擊產生的高加速度峰值。 我正在與單個 ADXL373 加速度計通信以通過 SPI 啟動。

我在 SPI 代碼上停留了一段時間,因為它只會從所有 3 個軸讀取 0。 我期望的問題仍然是我如何編寫讀/寫代碼。 在我執行它們的方式上,有什么突出的錯誤嗎?

ADXL373 數據表: https ://www.analog.com/media/en/technical-documentation/data-sheets/adxl373.pdf

// ADXL373 400g Accelerometer sensor connected to Arduino 2560 Mega Board

// V5: pin 3.3V
// GND: pin GND
// MOSI: pin 51
// MISO: pin 50
// SCLK: pin 52
// CS: pin 53

// the sensor communicates using SPI, so include the library:
#include <SPI.h>

const int CS = 53; //Chip Select (Arduino Mega Pin 53)

/////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Register Addresses ////////////////////////////////

byte XDATA_H = 0x08; // (0b00001000) X Data Register, High 8 MSB 
byte XDATA_L = 0x09; // (0b00001001) X Data Register, Low 4 MSB 
byte YDATA_H = 0x0A; // (0b00001010) Y Data Register, High 8 MSB 
byte YDATA_L = 0x0B; // (0b00001011) Y Data Register, Low 4 MSB 
byte ZDATA_H = 0x0C; // (0b00001100) Z Data Register, High 8 MSB 
byte ZDATA_L = 0x0D; // (0b00001101) Z Data Register, Low 4 MSB 
byte OFFSET_X = 0x20; // X Data Offset Register, Lower 4 bits
byte OFFSET_Y = 0x21; // Y Data Offset Register, Lower 4 bits
byte OFFSET_Z = 0x22; // Z Data Offset Register, Lower 4 bits
byte TIME_CTRL = 0x3D; // (0b00111101) Timing Control Register -> Select ODR (0b10000000) for 5120 Hz
byte MEASR_CTRL = 0x3E; // (0b00111110) Measurement Control -> Bandwidth set (0b00000100) for 2560 Hz
byte POWER_CTRL = 0x3F; // (0b00111111) Power Control Register -> Op. Mode and HPF off (0b00000111)
const byte WRITE = 0b11111110; // Reads with a 1, high
const byte READ = 0b00000001; // Writes with a 0, low

////////////////////////////////////////////////////////////////////////////////

// Establish variables to identify x, y, and z axis accelerations
int x_axis = 1;
int y_axis = 2;
int z_axis = 3;

void setup() 
{
  SPI.begin(); // Initialize SPI
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST); // Data for the device is sent MSB first, RW is last bit
  Serial.begin(115200);   // Establish a serial connection to display data through terminal
  pinMode(CS, OUTPUT);   // Set CS Pin Direction
  digitalWrite(CS, LOW);
  writeRegister(MEASR_CTRL, 0b00000100); // Set Measurement Mode to 2560Hz bandwidth (0x04)
  writeRegister(POWER_CTRL, 0b00000111); // Set full bandwidth measurement mode, HPF disabled (0x07)
  writeRegister(TIME_CTRL, 0b10000000); // Set ODR to 5120 Hz
  digitalWrite(CS, HIGH);
  delay(1);
}

void loop()
{
  Serial.print(" x = "); 
  Serial.print(getValue(x_axis));
  Serial.print(" y = "); 
  Serial.print(getValue(y_axis));
  Serial.print(" z = "); 
  Serial.println(getValue(z_axis));
  delay(0.2);
}

int getValue(int axis)
{
  int AccelData = 0;
  int Offset = 0;
  int high, low; 
  if (axis == 1)
  {
    high = readRegister(XDATA_H);
    low = readRegister(XDATA_L);
  }
  else if (axis == 2)
  {
    high = readRegister(YDATA_H);
    low = readRegister(YDATA_L);
  }
  else if (axis == 3)
  {
    high = readRegister(ZDATA_H);
    low = readRegister(ZDATA_L);
  }
  AccelData = (high << 4) | (low >> 4); // Merge 8 bits from 'high' with upper 4 of 'low' 
  AccelData = (AccelData - Offset)*200; // (Reading-Offset)*ScaleFactor --> 200mg/LSB for ADXL373
  return AccelData;
}

byte readRegister(byte thisRegister)
{
  byte result = 0;   // predeclare result to return
  // ADXL373 expects the register address in the upper 7 bits of the transmitted byte
  // Shift the register bits left by 1 to apply READ bit:
  thisRegister = thisRegister << 1;
  byte dataToSend = thisRegister | READ; // Combine register address with READ command
  digitalWrite(CS,LOW);  //Set the Chip Select pin low to start an SPI packet
  result = SPI.transfer(dataToSend);  // Tell device to read register and save response
  digitalWrite(CS, HIGH);  //Set CS high to close communcation
  return result;
}

void writeRegister(byte thisRegister, byte thisValue)
{
 // ADXL373 expects the register address in the upper 7 bits of the transmitted byte
 // Shift the register bits left by 1 bit to apply WRITE bit:
 thisRegister = thisRegister << 1;
 byte dataWrite = thisRegister & WRITE; // Combine the register address and WRITE command
 byte dataToSend = ((dataWrite << 8) | thisValue);
 digitalWrite(CS,LOW); //Set CS pin low to signal SPI packet start
 SPI.transfer(dataToSend); //Transfer the register address, RW, and desired register value over SPI
 digitalWrite(CS,HIGH); //Set the Chip Select pin high to signal the end of an SPI packet.
}

非常感謝任何指導。

您需要使用兩個 SPI.transfer() 語句,如氣壓傳感器的Arduino SPI 教程中的示例。 參見第 160 - 164 行:

158   // send the device the register you want to read:
159 
160   SPI.transfer(dataToSend);
161 
162   // send a value of 0 to read the first byte returned:
163 
164   result = SPI.transfer(0x00);

第一條語句告訴傳感器您要讀取哪個寄存器。 第二條語句返回數據(此示例中的傳感器與您的 ADXL 工作方式不完全相同,因此我認為您不必發送 0x00 即可開始讀取,但要點是相同的)。

SPI.transfer()的描述說它執行“同時發送和接收”,但也可以用作發送接收。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM