[英]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.