I'm trying to interface Arduino Uno with ADXL345 (Accelerometer) Over I2C Protocol. The register TWSR in the ATmega328p controller which supposed to give a set of predefined codes, is showing a status code 248.
I had searched for it but did not find any satisfactory answer for my problem. I am following the procedure mentioned in the Datasheet of ADXL345.
#define TWSR (*((volatile unsigned int *) 0xB9))
#define TWAR (*((volatile unsigned int *) 0xBA))
#define TWDR (*((volatile unsigned int *) 0xBB))
#define TWCR (*((volatile unsigned int *) 0xBC))
float X_Axis, Y_Axis, Z_Axis;
int x;
void setup()
{
Serial.begin(9600); //Serial Communication.
Serial.println("ADXL345 Interface.");
TWSR=0x00;
}
void loop()
{
Start();
SLA_Write();
X_Axis=REGAddress_X0();
Serial.println(" Partial X output X0=");
Serial.println(X_Axis);
}
void Start()
{
Start: //label
TWCR=0xA4;
delayMicroseconds(0.6); //Delay,As per mentioned in ADXL345 Datasheet.
Serial.print("TWSR in START Function:");
Serial.println(TWSR);
if(0x08 != TWSR)
{
goto Start; // jump to label.
}
delayMicroseconds(1.2); //t3-t5 Delay ADXL345 Datasheet.
}
void SLA_Write()
{
SLA_Write:
//delayMicroseconds(0.3);
TWDR=0xA6;
delayMicroseconds(1.6); //t2+t6+t5 (setup+hold+SCL high) time; ADXL345 Datasheet.
TWCR=0x84;
Serial.print("TWSR in SLAWrite Function:");
Serial.println(TWSR);
switch(TWSR)
{
case 0x18: Serial.println("SLA+W has been transmitted;ACK has been received 0x18");
break;
case 0x20: Serial.println("SLA+W has been transmitted;ACK has been received");
Start();
goto SLA_Write;
break;
case 0x38: Serial.println("Arbitration lost in SLA+W ordata bytes");
Start();
goto SLA_Write;
break;
}
}
int REGAddress_X0()
{
REGAddress_X0: // Label
TWDR=0x32; // X0 Register-ADXL345 Datasheet.
delayMicroseconds(1.6); //t2+t6+t5 (setup+hold+SCL high) time; ADXL345 Datasheet.
if(0x28 != TWSR)
{
goto REGAddress_X0; // jump to label.
}
//delayMicroseconds(1.6); //t2+t6+t5 (setup+hold+SCL high) time; ADXL345 Datasheet.
Start();
delayMicroseconds(0.6); // Repeated start setup time delay t7. ADXL345 Datasheet.
TWDR= 0xA7; //SLA+Read ATmega 328p Datashet & ADXL345 Datasheet.
TWCR= 0x84; // Clearing INT Flag. ATmega 328p Datasheet.
delayMicroseconds(1.6); //t2+t6+t5 (setup+hold+SCL high) time; ADXL345 Datasheet.
switch(TWSR)
{
case 0x40: Serial.println("SLA+W has been transmitted;ACK has been received 0x40");
break;
case 0x48: Serial.println("SLA+W has been transmitted;NOT ACK has been received 0x48");
Start();
SLA_Write();
goto REGAddress_X0;
break;
case 0x38: Serial.println("Arbitration lost in SLA+W ordata bytes 0x38");
Start();
SLA_Write();
goto REGAddress_X0;
break;
}
return TWDR;
}
The code is partial. There are two registers for each of the 3 Axis (ie X0 X1, Y0 Y1, Z0 Z1). Right now I am trying to get values from X0 register.
Can anyone help me out with a proper solution?