Reading temperature from MCP9801 via I2C with 8051

Discussion in 'Embedded Systems and Microcontrollers' started by Cable Guy, Mar 31, 2012.

  1. Cable Guy

    Thread Starter New Member

    Mar 23, 2012
    3
    0
    I am trying to communicate to a MCP9801 temperature sensor via I2C using a 8051 microcontroller.

    I wrote a routine to set the resolution in the config register to 0.0625 C and then read a byte from the temperature register in an array:

    Code ( (Unknown Language)):
    1.  
    2. #include <I2C.h>
    3.  
    4. void main()
    5. {
    6.         unsigned int i;
    7.     unsigned char a[8];
    8.  
    9.     while(1)
    10.     {
    11.  
    12.                 I2CInit();
    13.         I2CStart();
    14.  
    15.         I2CSend(0x90); //device adress: 1001 00 [COLOR="#0000FF"]0[/COLOR] - [COLOR="#0000FF"]write operation[/COLOR]
    16.         I2CAck();
    17.  
    18.         I2CSend(0x01); //pointer for selecting config register
    19.         I2CAck();
    20.  
    21.         I2CSend(0x60); //value to write in config register
    22.         I2CAck();
    23.    
    24.         I2CStop();
    25.  
    26.         I2CStart();
    27.         I2CSend(0x90); [COLOR="#FF0000"]// dummy write command - for selecting the temperature register[/COLOR]
    28.         I2CAck();
    29.        
    30.         I2CSend(0x02); //pointer for selecting the temperature register
    31.         I2CAck();
    32.  
    33.         I2CSend(0x91); //read command
    34.         I2CAck();
    35.  
    36.                 for(i=0;i<8;i++) //reading 8 bits from the hysteresis register into unsigned char array
    37.         {
    38.             a[i]=I2CRead();
    39.             if(i==7)
    40.                 I2CNak();
    41.             else I2CAck();
    42.         }// for
    43.  
    44.         I2CStop();
    45.  
    46.     }//while(1)
    47. }//main
    48.  
    49. [/i]


    When I look in the I2C debugger terminal in Proteus VSM simulator, this is what I see:

    http://imageshack.us/photo/my-images/814/simulation.jpg



    I don't see the value in the temperature register (0x1B) anywhere.

    And the coresponding error message is : [MCP980X] Pointer Invalid -> most probably it refers to the temperature register pointer, but what is going on there is a dummy write - here is the extract from the MCP9801 datasheet showing how to read from the temperature register:

    http://imageshack.us/photo/my-images/51/readingdiagram.jpg

    And here is the content of the I2C header I am using (program written in Keil):

    Code ( (Unknown Language)):
    1.  
    2. #include <reg51.h>
    3.  
    4. sbit SDA=P0^0;
    5. sbit SCL=P0^1;
    6.  
    7. void I2CInit()
    8. {
    9.     SDA=1;
    10.     SCL=1;
    11. }//I2CInit
    12.  
    13. void I2CStart()
    14. {
    15.     SCL = 1;
    16.     SDA = 0;
    17.     SCL = 0;
    18. }//I2CStart
    19.  
    20. void I2CRestart()
    21. {
    22.     SCL = 0;
    23.     SDA = 1;
    24.     SCL = 1;
    25.     SDA = 0;
    26. }//I2CRestart
    27.  
    28. void I2CStop()
    29. {
    30.     SCL = 0;
    31.     SDA = 0;
    32.     SCL = 1;
    33.     SDA = 1;
    34. }//I2CStop
    35.  
    36. void I2CAck()
    37. {
    38.     SDA = 0;
    39.     SCL = 1;
    40.     SCL = 0;
    41.     SDA = 1;
    42. }//I2CAck
    43.  
    44. void I2CNak()
    45. {
    46.     SDA = 1;
    47.     SCL = 1;
    48.     SCL = 0;
    49. }//I2CNak
    50.  
    51. void I2CSend(unsigned char Data)
    52. {
    53.     unsigned char i;
    54.  
    55.     for(i=0;i<8;i++)
    56.     {
    57.         SCL = 0;
    58.  
    59.         if((Data&0x80)==0)
    60.             SDA=0;
    61.         else SDA = 1;
    62.  
    63.         SCL=1;
    64.         Data<<=1;
    65.     }//for
    66.  
    67.     SCL = 0;
    68.     SDA = 1;
    69. }//I2CSend
    70.  
    71. unsigned char I2CRead()
    72. {
    73.     unsigned char i, Data=0;
    74.  
    75.     for(i=0;i<8;i++)
    76.     {
    77.         SCL=0;
    78.         SCL=1;
    79.  
    80.         if(SDA)
    81.             Data|=1;
    82.         Data<<=1;
    83.     }//for
    84.  
    85.     SCL = 0;
    86.     SDA = 1;
    87.  
    88.     return Data;
    89. }//I2CRead
    90.  
    91.  

    Also here is the MCP9801 datasheet for reference: http://www.datasheetcatalog.org/datasheet2/d/0jah5j3yagu1fft7wczs570sskfy.pdf

    What is it I am missing?

    Thank you for having the patience to go trough such a long post.
     
    Last edited by a moderator: Apr 1, 2012
  2. Cable Guy

    Thread Starter New Member

    Mar 23, 2012
    3
    0
    I have figure out my problem; anyone is free to laugh at my code, since I can't seem to be able to edit the previous message.:)

    I will be posting my complete thermostat project (C code and simulation screenshot) when it will be complete.
     
Loading...