Arduino SPI-problem med accelerometer LIS3DH

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
killernils
Inlägg: 39
Blev medlem: 25 december 2005, 17:05:29

Arduino SPI-problem med accelerometer LIS3DH

Inlägg av killernils »

Hejsan! Jag har suttit och lekt runt med SPI på en Arduino Due och försökt få den att kommunicera med en accelerometer, LIS3DH.
http://www.st.com/st-web-ui/static/acti ... 274221.pdf

Av vad jag kan tyda ifrån databladet så vill sensorn ha MSB-first och SPI_mode(3). Med de inställningarna så lyckas jag läsa olika register på sensorn, men jag kan inte skriva till dem.
Jag försöker skriva till ctrl_reg1, och sedan efter läsa från samma register för att bekräfta att skrivningen gick bra. Detta fungerar inte med Mode3, men till min förvåning fungerar det med SPI_Mode0!
Jag har läst genom databladet flera gånger och kommer alltid fram till slutsatsen att det skall vara mode3, men likväl är det mode0 som fungerar.
Kan någon förklara om databladet är fel, eller om jag är korkad?:)
mvh Henrik

Kod: Markera allt

#include <SPI.h>

//Register Addresses:
const int CTRL_REG1 = 0x20; //Register that can enable,disable axes and Powermodes
const int WHO_AM_I = 0x0F; //Dummy register, set at 0x33
const byte READ = 0b10000000;//LIS3DH's read command
const byte WRITE = 0b00111111;//LIS3DH's write command
const int ss = 10;//Arduino ss pin10

void setup() {  
  Serial.begin(9600);//Pc communication  
  pinMode(ss,OUTPUT); //set ss-pin to output
  
  SPI.begin();//initiate SPI
  SPI.setBitOrder(MSBFIRST);//page 23/42 in datasheet
  SPI.setDataMode(SPI_MODE3); //page 22/42-23/42 in datasheet
  SPI.setClockDivider(ss,21);// 4 MHz
  
  //get out of powerdown and set to 400Hz,all axis on.
  writeRegister(CTRL_REG1,0x77); //set controllreg1 to 0b01110111 (0x77)
  delay(100);//maybe not needed?
  Serial.println(readRegister(CTRL_REG1), HEX);//Make sure controllreg1 is actually set to 0x77. 
  delay(100);//maybe not needed?
}

void loop() {    
  delay(500);//just to have something to loop
}


byte readRegister(byte thisRegister)
{
    byte result = 0;   //result to return
    byte dataToSend = thisRegister | READ; //make sure that the two MSB are set to 10, to enable read-mode.
    
    digitalWrite(ss,LOW); //set slaveselect
    SPI.transfer(dataToSend);//Send a byte with "read-command and reg-adress"
    result = SPI.transfer(0x00);//Send whatever just to initiate transfer 
    digitalWrite(ss, HIGH);//Set the Chips Select pin high to end the SPI packet.
    
    return result;
}

void writeRegister(byte thisRegister, byte thisValue)
{
  //set the two MSB to 00, to enable write mode.
  byte dataToSend = thisRegister & WRITE;//Maybe not needed as LIS3dh reg-adress is always in lower 6bits?
  
  digitalWrite(ss,LOW);//Set Chip Select pin low to signal the beginning of an SPI packet
  SPI.transfer(dataToSend);//Transfer the register address over SPI
  SPI.transfer(thisValue);//Transfer the desired register value over SPI.
  digitalWrite(ss,HIGH);//Set the Chip Select pin high to signal the end of an SPI packet
}
EDIT: För att underlätta för er läsare.I databladet, under kap 6.2, står följande som jag tolkar till Mode3:
CS is the serial port enable and it is controlled by the SPI master. It goes low at the start of
the transmission and goes back high at the end. SPC is the serial port clock and it is
controlled by the SPI master. It is stopped high when CS is high (no transmission). SDI and SDO are respectively the serial port data input and output. Those lines are driven at the
falling edge of SPC and should be captured at the rising edge of SPC.
floppen
Inlägg: 109
Blev medlem: 14 september 2012, 13:28:32

Re: Arduino SPI-problem med accelerometer LIS3DH

Inlägg av floppen »

Hej

Har du fått ordning på detta?
Jag sitter nu med en LIS3DSH och har samma problem men får det att fungera om jag lägger på en paus efter att jag dragit CS låg och en innan jag sätter CS hög igen.

Kod: Markera allt

  CS_SPI_MEMS= 0;
  Delay_Cyc_Long(20);
  SPI1_Write(addres,0);
  SPI1_Write_Buff(buff,len,1);
  Delay_Cyc_Long(20);
  CS_SPI_MEMS= 1;
Vad jag kan se i databladet så ligger jag med marginal inom den tid dom säger även utan paus, och som du säger så fungerar det i mode 0 och med en paus så fungerar även mode 3.
Man blir lite nyfiken på hur lång paus man behöver för att det skall fungera säkert över temperatur.
Skriv svar