Ic2 programming interfacing DS895450 with an MMA8452Q accelerometer HELP!

Discussion in 'Embedded Systems and Microcontrollers' started by dekage, Apr 5, 2012.

  1. dekage

    Thread Starter New Member

    Apr 5, 2012
    2
    0
    Hi,
    Basically i did a program to read datas from this 3 axis accelerometer.
    however the results is 0xff for all 3 axis. May i know what might be the possible cause?

    Here is the code:

    Code ( (Unknown Language)):
    1.  
    2. #include <DS89C4XX.h>    //DS89C450 Microcontroller          
    3. #include <intrins.h>    //_nop_() function
    4. #include <stdio.h>        //sprintf() function
    5. #define  _Nop()  _nop_()
    6.  
    7. /*#define  OUT_X_MSB 0x01
    8. #define  OUT_X_LSB 0x02
    9. #define  OUT_Y_MSB 0x03
    10. #define  OUT_Y_LSB 0x04
    11. #define  OUT_Z_MSB 0x05
    12. #define  OUT_Z_LSB 0x06 */
    13. #define  WHO_AM_I  0x0D
    14. //#define  SLA       0x1C       //slave address
    15.  
    16. sbit SDA=P1^0;            
    17. sbit SCL=P1^1;
    18.  
    19. //i2c buffer
    20. void I2CBitDly()
    21.  // wait approximately 4.7uS
    22. { // tune to xtal. This works at 11.0592MHz
    23. unsigned int time_end = 10;
    24. unsigned int index;
    25. for (index = 0; index < time_end; index++);
    26. return;
    27. }
    28.  
    29. //i2c START
    30. //-------------------------------------------
    31. void I2CSendStart()
    32. {
    33.   SDA = 1;             // i2c start bit sequence
    34.   I2CBitDly();
    35.   SCL = 1;
    36.   I2CBitDly();
    37.   SDA = 0;
    38.   I2CBitDly();
    39.   SCL = 0;
    40.   I2CBitDly();
    41. }
    42. //-------------------------------------------
    43.  
    44. //i2c Stop
    45. //-------------------------------------------
    46. void I2CSendStop()
    47. {
    48.   SDA = 0;             // i2c stop bit sequence
    49.   I2CBitDly();
    50.   SCL = 1;
    51.   I2CBitDly();
    52.   SDA = 1;
    53.   I2CBitDly();
    54. }
    55. //--------------------------------------------
    56.  
    57. // Set SCL high, and wait for it to go high
    58. //--------------------------------------------
    59. void I2CSCLHigh(void)
    60. {
    61. register int err;
    62. SCL = 1;
    63. while (! SCL)
    64. {
    65. err++;
    66. if (!err)
    67. {
    68. return;
    69. }
    70. }
    71. }
    72. //---------------------------------------------
    73.  
    74. //Send function
    75. //---------------------------------------------
    76. void I2CSendByte(unsigned char bt)
    77. {
    78. register unsigned char i;
    79. for (i=0; i<8; i++)
    80. {
    81. if (bt & 0x80) SDA = 1; // Send each bit, MSB first changed 0x80 to 0x01
    82. else SDA = 0;
    83. I2CSCLHigh();
    84. I2CBitDly();
    85. SCL = 0;
    86. I2CBitDly();
    87. bt = bt << 1;
    88. }
    89. SDA = 1; // Check for ACK
    90. I2CBitDly();
    91. I2CSCLHigh();
    92. I2CBitDly();
    93. if (SDA)
    94. SCL = 0;
    95. I2CBitDly();
    96. SDA = 1; // end transmission
    97. SCL = 1;
    98. }
    99. //-----------------------------------------------
    100.  
    101. // Transmit to SDA
    102. //---------------------------------------------
    103. void I2CSendAddr(unsigned char addr, unsigned char rd)
    104. {
    105. I2CSendStart();
    106. I2CSendByte(addr+rd); // send address byte
    107. }
    108. //---------------------------------------------
    109.  
    110. // Receive from SDA
    111. //--------------------------------------------------
    112. unsigned char I2CGetByte(unsigned char lastone) // last one == 1 for last byte; 0 for any other byte
    113. {
    114. register unsigned char i, res;
    115. res = 0;
    116. for (i=0;i<8;i++) // Each bit at a time, MSB first
    117. {
    118. I2CSCLHigh();
    119. I2CBitDly();
    120. res *= 2;
    121. if (SDA) res++;
    122. SCL = 0;
    123. I2CBitDly();
    124. }
    125. SDA = lastone; // Send ACK according to 'lastone'
    126. I2CSCLHigh();
    127. I2CBitDly();
    128. SCL = 0;
    129. SDA = 1; // end transmission
    130. SCL=1;
    131. I2CBitDly();
    132. return(res);
    133. }
    134. //----------------------------------------------------------
    135.  
    136. //delay
    137. //--------------------------------------------------
    138. void delay(int count)
    139. {
    140.     int i,j;
    141.  
    142.     for (i=0;i<count;i++){
    143.     for (j=0;j<1200;j++); }
    144. }
    145. //--------------------------------------------------
    146. ///////////////////////////////////////////SERIAL PORT/////////////////////////////////////////////////
    147. void Tx(unsigned char c)
    148. {
    149.     while (TI_0==0);
    150.     TI_0=0;
    151.     SBUF0=c;
    152. }
    153. ////////////////////////////////////////////////////////////////////////////////////////////////////////
    154.  
    155. //////////////////////////////////////////Digital Transfer//////////////////////////////////////////////
    156. void Tx_char(unsigned char c)
    157. {
    158.     unsigned char s[4];
    159.     int i;
    160.  
    161.     c=c&0xff;
    162.     sprintf(s,"%#x",(int)c);         // write into string.
    163.     for (i=0;i<4;i++) Tx(s[i]);
    164. }
    165. /////////////////////////////////////////////////////////////////////////////////////////////////////////
    166.  
    167. //////////////////////////////////////////String port////////////////////////////////////////////////////
    168. void Uart_Tx2(unsigned char x)
    169. {
    170.     while (TI_0==0);
    171.     TI_0=0;
    172.     SBUF0=x;
    173. }
    174. ////////////////////////////////////////////////////////////////////////////////////////////////////////
    175.  
    176. ////////////////////////////////////////////Send String//////////////////////////////////////////
    177. void sendstring (char *String)
    178. {
    179.     int i=0;    //set counter to 0
    180.     while(String[i])
    181.     {
    182.         Uart_Tx2(String[i++]);
    183.     }
    184.  
    185. }
    186. ////////////////////////////////////////////////////////////////////////////////////////////////
    187.  
    188. void main ()
    189. {
    190.      unsigned char value;
    191.      
    192.      
    193.      SCON1 = 0x52;  
    194.      SCON0 = 0x52;  
    195.      TMOD  = 0x20;    
    196.      TCON  = 0x69;      
    197.      TH1   = 0xFD;
    198.      delay(500);
    199.    
    200.      sendstring("System boot...");
    201.      while(1)
    202.          
    203.      {
    204.          //READ X_MSB
    205.         //sendstring(" ");
    206.         sendstring(" XMSB: ");
    207.         delay(500);
    208.         I2CSendAddr(0x1C,0x38);
    209.         I2CSendByte(0x01);
    210.         I2CSendAddr(0x1C,0x39);
    211.         value = I2CGetByte(1);
    212.         Tx_char(value);
    213.         I2CSendStop();
    214.         delay(1000);
    215.  
    216.         sendstring(" XLSB: ");
    217.         delay(500);
    218.         I2CSendAddr(0x1C,0x38);
    219.         I2CSendByte(0x02);
    220.         I2CSendAddr(0x1C,0x39);
    221.         value = I2CGetByte(1);
    222.         Tx_char(value);
    223.         I2CSendStop();
    224.         delay(1000);
    225.  
    226.         sendstring(" YMSB: ");
    227.         delay(500);
    228.         I2CSendAddr(0x1C,0x38);
    229.         I2CSendByte(0x03);
    230.         I2CSendAddr(0x1C,0x39);
    231.         value = I2CGetByte(1);
    232.         Tx_char(value);
    233.         I2CSendStop();
    234.         delay(1000);
    235.  
    236.         sendstring(" YLSB: ");
    237.         delay(500);
    238.         I2CSendAddr(0x1C,0x38);
    239.         I2CSendByte(0x04);
    240.         I2CSendAddr(0x1C,0x39);
    241.         value = I2CGetByte(1);
    242.         Tx_char(value);
    243.         I2CSendStop();
    244.         delay(1000);
    245.  
    246.         sendstring(" ZMSB: ");
    247.         delay(500);
    248.         I2CSendAddr(0x1C,0x38);
    249.         I2CSendByte(0x05);
    250.         I2CSendAddr(0x1C,0x39);
    251.         value = I2CGetByte(1);
    252.         Tx_char(value);
    253.         I2CSendStop();
    254.         delay(1000);
    255.  
    256.         sendstring(" ZLSB: ");
    257.         delay(500);
    258.         I2CSendAddr(0x1C,0x38);
    259.         I2CSendByte(0x06);
    260.         I2CSendAddr(0x1C,0x39);
    261.         value = I2CGetByte(1);
    262.         Tx_char(value);
    263.         I2CSendStop();
    264.         delay(1000);
    265.   }
    266.          
    267. }
    268.  
    269. [/i][/i]
     
    Last edited by a moderator: Apr 5, 2012
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    0xFF is what an I2C interface appears to read if you assume the addressing was good and don't check the ACK/NAK bit and assume you were ACKed.

    So the slave wasn't responding, the Data line stayed at it's default pull up value of one, and your master clocked those in.

    Do you have a scope to watch the transaction? If not, I2C works at DC speed so you can literally watch it on a voltmeter.
     
  3. dekage

    Thread Starter New Member

    Apr 5, 2012
    2
    0
    Hi, i have tried to re-program this chip just to read for acknowledgement by sending the start up code for I2C followed by a simple sending of data to the chip. However, i could not receive any acknowledgement from the accelerometer. Im interfacing it with a DS89C450 chip XTAL 11.0592hz . using only 2 ports 1.0 and 1.1.

    May i ask what might be the problem?
    (* The program is stuck at sending "nack" which i believe SDA is not pulled low )

    here is the current edited program changed:

    Code ( (Unknown Language)):
    1.  
    2. #include <DS89C4XX.h>    //DS89C450 Microcontroller  
    3.  
    4.  
    5. sbit SDA=P1^0;            
    6. sbit SCL=P1^1;
    7. //--------------------------Transmit----------------------------------
    8. void Uart_Tx2(unsigned char c)
    9. {
    10.     while (TI_0==0);
    11.     TI_0=0;
    12.     SBUF0=c;
    13. }
    14.  
    15. // ----------------------Transmit string ------------------------------------------------------
    16. void sendstring (char *String)
    17. {
    18.     int i=0;    //set counter to 0
    19.     while(String[i])
    20.     {
    21.         Uart_Tx2(String[i++]);
    22.     }
    23.  
    24. }  
    25.  
    26.  
    27. //-------------------------------Delay -----------------------------------------
    28. void I2CBitDly()   // wait approximately 4.7uS
    29. { // tune to xtal. This works at 11.0592MHz
    30. unsigned int time_end = 10;
    31. unsigned int index;
    32. for (index = 0; index < time_end; index++);
    33. return;
    34. }
    35.  
    36.  
    37. //-------------------------------------------Start--------------------------
    38. void I2CSendStart(void)
    39. {
    40. SDA = 1;
    41. I2CBitDly();
    42. SCL = 1;
    43. I2CBitDly();
    44. SDA = 0;
    45. I2CBitDly();
    46. SCL = 0;
    47. I2CBitDly();
    48. }
    49.  
    50. //-------------------------------------------STOP-----------------------------
    51. void I2CSendStop(void)
    52. {
    53. SDA = 0;
    54. I2CBitDly();
    55. SCL = 1;
    56. I2CBitDly();
    57. SDA = 1;
    58. I2CBitDly();
    59. }
    60.  
    61. //-----------------------------------------SEND data---------------------------
    62. void I2CSendByte(unsigned char bt)
    63. {
    64. register unsigned char i;
    65. for (i=0; i<8; i++)
    66. {
    67. if ((bt<<i)&0x80) SDA = 1; // Send each bit
    68. else SDA = 0;
    69.  
    70. SCL = 1;
    71. I2CBitDly();
    72. SCL = 0;
    73. I2CBitDly();
    74.  
    75. }
    76. SDA = 1; // Check for ACK  by forcing SDA high
    77. I2CBitDly();
    78. SCL = 1;    // 9th clock high.
    79. I2CBitDly();
    80.  
    81.  
    82. while (SDA == 1) //waits until SDA is pulled low
    83. {
    84.     sendstring("nack");          // SDA is not pulled low. nack is sent.
    85.    
    86. }
    87.    SCL = 0;
    88.  
    89.  
    90. I2CBitDly();
    91. SDA = 1; // end transmission
    92. SCL = 1;
    93. }
    94.  
    95.  
    96.  
    97.  
    98. //---------------MAIN---------------------------------
    99. void main ()
    100. {
    101. //     unsigned char value;    
    102.  
    103.         SCON1  = 0x52;  
    104.      SCON0 = 0x52;
    105.      TMOD  = 0x20;    
    106.      TCON  = 0x69;      
    107.      TH1   = 0xFD;    //Buad Rate: 9600 bps
    108.      
    109.  
    110.      
    111.      I2CSendStart();
    112.      I2CSendByte(0x38);
    113.    
    114.    while(1)
    115.    {
    116.            
    117.  
    118.    };
    119. }
    120. [/i]
     
    Last edited by a moderator: Apr 11, 2012
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    I don't see anything wrong in your start signal nor the byte send. What metering do you have? Scope? DVM? Scope is faster but you can use a DVM (or even 2 LEDs) to see what is happening on the I2C lines as it works at DC speeds.


    It may be necessary to add a delay here in I2CSendByte():
    Code ( (Unknown Language)):
    1. if ((bt<<i)&0x80) SDA = 1; // Send each bit
    2. else SDA = 0;
    3. I2CBitDly();        // add delay here
     
Loading...