已回答假定已回答

ADXL345 不能读

hoygm 在 2017-5-3 詢問的問題
最後回覆由neilzhao於2017-5-24提供

各位好!我用ADXL345出现问题,一筹莫展,查不出问题所在。

mcu用stc15w102,IIC读写。

主函数中如果没有“devid = ADXL_ReadOneByte(0x00);”语句,串口发送“COMM_SendOneByte(0xA5);”发送到电脑上串口助手的数据正常;如果加上“devid = ADXL_ReadOneByte(0x00);”语句,串口发送“COMM_SendOneByte(0xA5);”发送到电脑上串口助手的数据就不正常。说明是ADXL_ReadOneByte(xxx);程序有问题。但反反复复检查就是查不出来问题所在。请大家帮助,不胜感谢!下面是相关程序:

// Use mcu STC15W102

void Dly5us(void)  //@11.0592MHz
{
  uchr i;
nop_();
//i = 11;
  i = 8;
while (--i);
}

void ADXL_StrtTrans(void)
{
  SDA_TXD = 1;
  SCL = 1;   
  Dly5us(); 
  SDA_TXD = 0;
  Dly5us(); 
  SCL = 0;
//Dly5us();       // tem
}

void ADXL_StopTrans(void)
{
  SDA_TXD = 0;
  SCL = 1;   
  Dly5us(); 
  SDA_TXD = 1;
  Dly5us(); 
//SCL = 0;      // tem
}

void ADXL_WritAck(bit ack)
{                           
  SDA_TXD = ack;
  SCL = 1;     
  Dly5us();   
  SCL = 0;     
  Dly5us();
//SDA_TXD = !SDA_TXD;   // tem
}

bit ADXL_ReadAck(void)
{
//SDA_TXD = 1;   // tem
  SCL = 1;    
  Dly5us();  
  CY = SDA_TXD;
  SCL = 0;    
  Dly5us();  
  return CY;
}

void ADXL_WritEightBit(uchr dat)
{
  uchr i;
  for (i=0; i<8; i++)  
  {                    
    dat <<= 1;         
    SDA_TXD = CY;
  //Dly5us();       // tem
    SCL = 1;           
    Dly5us();         
    SCL = 0;           
    Dly5us();       //
  }
  ADXL_ReadAck();   //
}

uchr ADXL_ReadEightBit(void)
{
  uchr i;
  uchr dat = 0;
  SDA_TXD = 1;         
  for (i=0; i<8; i++)  
  {
    dat <<= 1;        //
    SCL = 1;           
    Dly5us();         
    dat |= SDA_TXD;
  //dat <<= 1;        // tem
    SCL = 0;           
    Dly5us();         
  }
  return dat;
}

void ADXL_WriteOneByte(uchr AdxlRegAddr,uchr EightBitData)
{
  ADXL_StrtTrans();                  // ADXL345 start transmission
  ADXL_WritEightBit(ADXL_SLV_ADDR);  // write the IIC slave address of device into ADXL345
//ADXL_ReadAck();                    // tem
  ADXL_WritEightBit(AdxlRegAddr);    // write the register address into ADXL345
//ADXL_ReadAck();                    // tem
  ADXL_WritEightBit(EightBitData);   // write the data into register of ADXL345
//ADXL_ReadAck();                    // tem
  ADXL_StopTrans();                  // ADXL345 stop transmission
}

uchr ADXL_ReadOneByte(uchr AdxlRegAddr)

  uchr AdxlReadDatBuf;
  ADXL_StrtTrans();                     // ADXL345 start transmission
  ADXL_WritEightBit(ADXL_SLV_ADDR);     // write the IIC slave address of device into ADXL345
//ADXL_ReadAck();                       // tem
  ADXL_WritEightBit(AdxlRegAddr);       // write the register address into ADXL345
//ADXL_ReadAck();                       // tem
  ADXL_StrtTrans();                     // ADXL345 start transmission
  ADXL_WritEightBit(ADXL_SLV_ADDR+1);   // write the IIC slave address of device into ADXL345
//ADXL_ReadAck();                       // tem
  AdxlReadDatBuf = ADXL_ReadEightBit(); // register data in ADXL345 is readed out
  ADXL_WritAck(1);                      // Send ACK to ADXL345
  ADXL_StopTrans();                     // ADXL345 stop transmission
  return AdxlReadDatBuf;
}

void ADXL_Init(void)
{
  ADXL_WriteOneByte(ADXL_DATA_FORMAT, 0x0B);   //Set DATA_FORMAT:mesurement scope,+ or - 16 gram,13 bit mode.
  ADXL_WriteOneByte(ADXL_BW_RATE,     0x08);   //Set BW_RATE:Rate = 25Hz.
  ADXL_WriteOneByte(ADXL_POWER_CTL,   0x08);   //Set POWER_CTL:mesurement mode is started.
  ADXL_WriteOneByte(ADXL_INT_ENABLE,  0x80);   //Set INT_ENABLE:DATA_READY interrupt is inhibit.
  ADXL_WriteOneByte(ADXL_OFFSETX,     0x00);   //Set ADXL_OFFSETX.
  ADXL_WriteOneByte(ADXL_OFFSETY,     0x00);   //Set ADXL_OFFSETY.
  ADXL_WriteOneByte(ADXL_OFFSETZ,     0x05);   //Set ADXL_OFFSETZ.
}

void main(void)
{
  ADXL_Init();
  while(1)                                  
  {                                         
    devid = ADXL_ReadOneByte(0x00);         
    COMM_SendOneByte(0xA5);                 
  }                                                      
}

結果