tough time with AT24C16 EEPROM, code attached

Discussion in 'Embedded Systems and Microcontrollers' started by hadeedunhaad, May 2, 2011.

  1. hadeedunhaad

    Thread Starter New Member

    Apr 22, 2011
    24
    0
    hi all, i'm stuck with this eeprom for last one week. Initially i could write and read from EEPROM (AT24C16), but any one in an execution, that is if i write a byte then my next function of reading a byte wont work and vice versa. And the page read/write was also not working. So i started to sniff around my 'stop' protocol for I2C, but to no avail. I continued troubleshooting and now i ended up with NOTHING. I've lost even my previous output. No read and no write. Im using AT89C2051 micro-controller. Code is provided below. Any help will be greatly appreciated.

    ; program for AT89C2051
    ; layout details
    ; write protect pin (eeprom) is connected to gnd
    ; Xtal used is 20Mhz
    ; R4 memmory address1
    ; R5 eeprom data
    ; status led connected to p1.3 is sinked for switching ON
    ; SDA and SCL pins are provided with pull ups - 4.7k
    led EQU P1.3 ; Led for the status indication
    sda EQU P3.7 ;
    scl EQU P1.2 ;
    ;===============================================
    ORG 0000h
    sjmp start
    ;===============================================
    ORG 0030h ; Initialization
    start:
    mov sp, #30h ; moving the stack pointer
    setb led ; put the LED off
    ;======================================================== Main Program
    mov r4,#00h ;mem location
    mov r5,#14h ;data
    lcall write_data
    mov r4,#01h ;mem location
    mov r5,#15h ;data
    lcall write_data
    clr led
    sjmp $
    ;==========================================================
    ;=========================================================
    ; Sub routines for I2C communication (EEPROM)
    ;=========================================================
    write_data:
    acall eeprom_start
    mov a,#0a0h
    acall send_data
    mov a,r4 ;location address
    acall send_data
    mov a,r5 ;data to be send
    lcall send_data
    acall eeprom_stop
    ret
    ;=========================================================
    read_data:
    acall eeprom_start
    mov a,#0a0h
    acall send_data
    mov a,r4 ;location address
    acall send_data
    acall eeprom_start
    mov a,#0a1h
    acall send_data
    acall get_data
    acall eeprom_stop
    ret
    ;=========================================================
    eeprom_start:
    setb scl
    nop
    setb sda
    nop
    nop
    clr sda
    nop
    clr scl
    nop
    nop
    nop
    ret
    ;=========================================================
    eeprom_stop: setb sda
    nop
    nop
    setb scl
    nop
    nop
    clr scl
    nop
    nop
    nop
    ret
    ;=========================================================
    send_data: mov r7,#00h
    senda: rlc a
    mov sda,c
    acall clock
    inc r7
    cjne r7,#08,senda
    setb sda
    nop
    setb scl
    jb sda, $
    clr scl
    nop
    nop
    nop
    ; acall eeprom_delay
    ret
    ;=========================================================
    get_data:
    mov r7,#00h
    setb sda
    get: setb scl
    nop
    nop
    mov c,sda
    rlc a
    inc r7
    clr scl
    nop
    nop
    nop
    cjne r7,#08,get
    mov r1,a
    ret
    ;=========================================================
    clock : setb scl
    nop
    nop
    clr scl
    nop
    nop
    nop
    ret
    ;=========================================================
    eeprom_delay : mov r7,#16 ;delay of 4.9 msec
    eepromd: mov r2,#0ffh
    djnz r2,$
    djnz r7,eepromd
    ret
    ;=====================================================
    /*
    ack:
    setb sda
    nop
    setb scl
    nop
    nop
    clr sda
    nop
    nop
    clr scl
    nop
    nop
    nop
    ret
    ;=====================================================
    no_ack:
    clr sda
    setb scl
    nop
    nop
    setb sda
    clr scl
    nop
    nop
    nop
    ret */
    ;=====================================================
    end;
     
  2. hadeedunhaad

    Thread Starter New Member

    Apr 22, 2011
    24
    0
    Hey all ! is there no one who can help me in this. Im waiting and i cant find any answer. i'm re posting my code.


    Code ( (Unknown Language)):
    1. ; layout details
    2. ; write protect pin (eeprom) is connected to gnd
    3.  
    4. ; Xtal used is 20Mhz
    5. ; R4 memmory address1
    6. ; R5 eeprom data
    7. ; status led connected to p1.3 is sinked for switching ON
    8. ; SDA and SCL pins are provided with pull ups - 4.7k
    9.  
    10. led            EQU     P1.3          ; Led for the status indication
    11. sda         EQU     P3.7          ;
    12. scl            EQU     P1.2          ;
    13. ;===============================================
    14.    
    15.    ORG 0000h
    16.    sjmp start    
    17. ;===============================================
    18.  
    19.    ORG 0030h                            ; Initialization
    20.        
    21.  start:
    22.  
    23.  mov   sp,  #30h      ; moving the stack pointer
    24.  setb  led               ; put the LED off    
    25.                                                                                                                                                                                                                                                                                                      
    26.  ;======================================================== Main Program
    27.  
    28.                
    29.        mov r4,#00h              ;mem location
    30.        mov r5,#14h              ;data
    31.     lcall write_data    
    32.                                  
    33.     mov r4,#01h              ;mem location    
    34.     mov r5,#15h              ;data
    35.     lcall write_data
    36.  
    37.     clr led
    38.    
    39.     sjmp $
    40.                
    41. ;==========================================================
    42.        
    43. ;=========================================================
    44. ; Sub routines for I2C communication (EEPROM)                      
    45. ;=========================================================
    46.  
    47. write_data:    
    48.                 acall eeprom_start
    49.                 mov a,#0a0h          
    50.                 acall send_data
    51.                 mov a,r4              ;location address
    52.                 acall send_data
    53.                 mov a,r5              ;data to be send
    54.                 lcall send_data
    55.                 acall eeprom_stop
    56.                    ret  
    57. ;=========================================================
    58. read_data:
    59.                 acall eeprom_start
    60.                 mov a,#0a0h
    61.                 acall send_data
    62.                 mov a,r4          ;location address
    63.                 acall send_data
    64.                 acall eeprom_start
    65.                 mov a,#0a1h
    66.                 acall send_data
    67.                 acall get_data
    68.                 acall eeprom_stop
    69.                 ret
    70. ;=========================================================
    71. eeprom_start:  
    72.                 setb scl
    73.                 nop
    74.                 setb sda
    75.                 nop
    76.                 nop
    77.                 clr sda
    78.                 nop
    79.                 clr scl
    80.                 nop
    81.                 nop
    82.                  nop              
    83.                 ret
    84. ;=========================================================
    85. eeprom_stop:   setb sda
    86.                nop
    87.                nop
    88.                setb scl
    89.                nop
    90.                nop
    91.                clr scl
    92.                nop
    93.                nop
    94.                nop
    95.                ret
    96. ;=========================================================
    97. send_data:     mov r7,#00h
    98.        senda:  rlc a
    99.                mov sda,c
    100.                acall clock
    101.                inc r7
    102.                cjne r7,#08,senda
    103.                setb sda
    104.                nop
    105.                setb scl    
    106.                jb sda, $
    107.                clr scl
    108.                nop
    109.                nop                        
    110.                nop
    111.             ;  acall eeprom_delay
    112.                ret                                      
    113. ;=========================================================
    114. get_data:
    115.                mov r7,#00h
    116.                setb sda
    117.           get: setb scl
    118.                nop
    119.                nop
    120.                mov c,sda
    121.                   rlc a
    122.                inc r7
    123.                clr scl
    124.                nop
    125.                nop
    126.                nop
    127.                cjne r7,#08,get
    128.                mov r1,a
    129.                ret
    130. ;=========================================================
    131. clock :        setb scl
    132.                nop
    133.                nop
    134.                clr scl
    135.                nop
    136.                nop
    137.                nop
    138.                ret
    139. ;=========================================================
    140. eeprom_delay :  mov r7,#16      ;delay of  4.9 msec
    141.        eepromd: mov r2,#0ffh
    142.                 djnz r2,$
    143.                 djnz r7,eepromd
    144.                 ret
    145. ;=====================================================    
    146. /*
    147.  ack:
    148.      setb sda
    149.     nop
    150.     setb scl
    151.      nop
    152.     nop
    153.     clr sda
    154.     nop
    155.     nop
    156.     clr scl
    157.      nop
    158.     nop
    159.     nop
    160.  ret
    161. ;=====================================================
    162.  no_ack:
    163.       clr sda
    164.      setb scl
    165.      nop
    166.      nop
    167.      setb sda
    168.      clr scl
    169.      nop
    170.      nop    
    171.      nop
    172.  ret   */
    173. ;=====================================================      
    174. end;
    175.  
     
  3. hadeedunhaad

    Thread Starter New Member

    Apr 22, 2011
    24
    0
    i think its time for me to look into some other forums !! :(
     
  4. GetDeviceInfo

    Senior Member

    Jun 7, 2009
    1,571
    230
    this is writing/reading an RTC at address 0xD0

    Code ( (Unknown Language)):
    1.  
    2. //------------------------------------------------------------------------------
    3. // I/O Port Defines
    4. //------------------------------------------------------------------------------
    5. #define   SDL   P2_1   // Serial data
    6. #define   SCK   P2_0   // Serial clock
    7. #define   M41T56   0xD0   // RTC address
    8. //------------------------------------------------------------------------------
    9. // I2C Functions - Bit Banged
    10. //------------------------------------------------------------------------------
    11. void i2c_start (void);      // Sends I2C Start Trasfer
    12. void i2c_stop (void);      // Sends I2C Stop Trasfer
    13. void i2c_write (BYTE input_data); // Writes data over the I2C bus
    14. BYTE i2c_read ();    // Reads data from the I2C bus
    15.  
    16. //------------------------------------------------------------------------------
    17. // I2C Peripheral Function Prototypes
    18. //------------------------------------------------------------------------------
    19. BYTE read_device(BYTE Device, BYTE Reg);
    20. void write_device (BYTE Device, BYTE Reg, BYTE Data);
    21.  
    22. void main (void)
    23. {
    24.  BYTE x;
    25.  BYTE Val;
    26.  // Set time
    27.  write_device(M41T56,0x00,0x00);   // Secs
    28.  write_device(M41T56,0x01,0x00);   // mins
    29.  write_device(M41T56,0x02,0x00);   // hrs
    30.  write_device(M41T56,0x03,0x01);   // days
    31.  write_device(M41T56,0x04,0x21);   // date
    32.  write_device(M41T56,0x05,0x02);   // month
    33.  write_device(M41T56,0x06,0x09);   // year
    34.  write_device(M41T56,0x07,0x00);   // control
    35.  // Looping read out of time registers
    36.  while(1)
    37.  {
    38.   for(x=0; x<8; x++)
    39.   {
    40.    Val = read_device(M41T56,0x00 + x);
    41.   }
    42.   delay(5000);
    43.  }
    44. }
    45.  
    46. void write_device (BYTE Device, BYTE Reg, BYTE Data)
    47. {
    48.     i2c_start();                     // Send I2C Start Transfer
    49.     i2c_write(Device);           // Send identifier I2C address - Write
    50.     i2c_write(Reg);               // Send control byte to device
    51.     i2c_write(Data);    
    52.     i2c_stop();                    // Send I2C Stop Transfer
    53. }
    54.  
    55.  
    56. BYTE read_device(BYTE Device, BYTE Reg)
    57. {
    58.     BYTE data_in;
    59.     i2c_start();                     // Send I2C Start Transfer
    60.     i2c_write(Device);            // Send identifier I2C address - Write
    61.     i2c_write(Reg);                // Send control byte to device (last 2 bits is the channel)
    62.     i2c_stop();                      // Send I2C Stop Transfer
    63.     i2c_start();                     // Send I2C Start Transfer
    64.     i2c_write(Device | 0x01);  // Send identifier I2C address - Read
    65.     data_in = i2c_read();       // Read the channel number
    66.     return (data_in);                
    67. }
    68.  
    69.  
    70.  //------------------------------------------------------------------------------
    71. // I2C Functions - Bit Banged
    72. //------------------------------------------------------------------------------
    73. //------------------------------------------------------------------------------
    74. //  Routine: i2c_start
    75. // Inputs:  none
    76. // Outputs: none
    77. // Purpose: Sends I2C Start Trasfer - State "B"
    78. //------------------------------------------------------------------------------
    79. void i2c_start (void)
    80. {
    81.  SDL = HIGH;       // Set data line high
    82.  SCK = HIGH;       // Set clock line high
    83.  SDL = LOW;       // Set data line low (START SIGNAL)
    84.  SCK = LOW;        // Set clock line low
    85. }
    86. //------------------------------------------------------------------------------
    87. //  Routine: i2c_stop
    88. // Inputs:  none
    89. // Outputs: none
    90. // Purpose: Sends I2C Stop Trasfer - State "C"
    91. //------------------------------------------------------------------------------
    92. void i2c_stop (void)
    93. {
    94.  BYTE input_var;
    95.  SCK = LOW;        // Set clock line low
    96.  SDL = LOW;       // Set data line low
    97.  SCK = HIGH;       // Set clock line high
    98.  SDL = HIGH;       // Set data line high (STOP SIGNAL)
    99.  input_var = SDL;      // Put port pin into HiZ
    100. }
    101. //------------------------------------------------------------------------------
    102. //  Routine: i2c_write
    103. // Inputs:  output byte
    104. // Outputs: none
    105. // Purpose: Writes data over the I2C bus
    106. //------------------------------------------------------------------------------
    107. void i2c_write (BYTE output_data)
    108. {
    109.  BYTE index;
    110.  for(index = 0; index < 8; index++)   // Send 8 bits to the I2C Bus
    111.  {                                    
    112.        SDL = ((output_data & 0x80) ? 1 : 0);  // Output the data bit to the I2C Bus
    113.        output_data  <<= 1;              // Shift the byte by one bit
    114.        SCK = HIGH;               // Clock the data into the I2C Bus
    115.        SCK = LOW;    
    116.  }
    117.        SDL = HIGH;        // Put data pin into read mode
    118.        SCK = HIGH;                // Clock the ACK from the I2C Bus
    119.        SCK = LOW;    
    120. }
    121. //------------------------------------------------------------------------------
    122. //  Routine: i2c_read
    123. // Inputs:  none
    124. // Outputs: input byte
    125. // Purpose: Reads data from the I2C bus
    126. //------------------------------------------------------------------------------
    127. BYTE i2c_read (void)
    128. {
    129.     BYTE index, input_data;
    130.     SDL = 1;       // Put data pin into read mode
    131.     input_data = 0x00;
    132.     for(index = 0; index < 8; index++)   // Send 8 bits to the I2C Bus
    133.     {
    134.         input_data <<= 1;     // Shift the byte by one bit
    135.         SCK = HIGH;               // Clock the data into the I2C Bus
    136.         input_data |= SDL;        // Input the data from the I2C Bus
    137.         SCK = LOW;    
    138.     }
    139.     return (input_data);
    140. }
    141.  
     
    Last edited: May 4, 2011
  5. nigelwright7557

    Senior Member

    May 10, 2008
    487
    71
    You need to go back to the data book on i2c and make sure all your commands are correct.
    Also check your timing, it could be you are clocking too quickly.
     
  6. hadeedunhaad

    Thread Starter New Member

    Apr 22, 2011
    24
    0
    yes i'm checking, shall let you know ASAP. Thank you for your reply.
     
  7. hadeedunhaad

    Thread Starter New Member

    Apr 22, 2011
    24
    0
    again all, here is the present status.
    It returned to the earlier state. Reading is possible and Writing is possible separately. Hence i don't doubt much on my clocking delay. Thanks for your suggestion nigelwright7557. And also i had put my initial delays based upon the data sheet and now i've placed more timings.

    I noticed the following things. Before that im posting my current code.

    Code ( (Unknown Language)):
    1.  
    2. ; layout details
    3. ; write protect pin (eeprom) is connected to gnd
    4.  
    5. ; Xtal used is 20Mhz
    6. ; R4 memmory address1
    7. ; R5 eeprom data
    8. ; status led connected to p1.3 is sinked for switching ON
    9. ; SDA and SCL pins are provided with pull ups - 4.7k
    10.  
    11. led            EQU     P1.3          ; Led for the status indication
    12. sda         EQU     P3.7          ;
    13. scl            EQU     P1.2          ;
    14. ;===============================================
    15.    
    16.    ORG 0000h
    17.    sjmp start    
    18. ;===============================================
    19.  
    20.    ORG 0030h                            ; Initialization
    21.        
    22.  start:
    23.  
    24.  mov   sp,  #30h             ; moving the stack pointer
    25.  setb  led                 ; put the LED off    
    26.                                                                                                                                                                                                                                                                                                      
    27.  ;======================================================== Main Function
    28.  
    29.  
    30.     mov r4,#00h                ;mem location
    31.     mov r5,#11h                ;data
    32.     lcall write_data    
    33.     mov a,#11h              ;data to be send
    34.     lcall send_data
    35.     mov a,#11h              ;data to be send
    36.     lcall send_data
    37.     mov a,#11h              ;data to be send
    38.     lcall send_data
    39.     mov a,#11h              ;data to be send
    40.     lcall send_data
    41.     acall eeprom_stop
    42.  
    43.     mov r4,#05h              ;mem location
    44.      mov r5,#22h              ;data
    45.     lcall write_data
    46.     acall eeprom_stop
    47.  
    48. /*                                              
    49.  
    50. readagain:
    51.     mov r4,#04h              ;mem location    
    52.     lcall read_data
    53.     cjne r1, #11h, readagain         */
    54.  
    55.     clr led
    56.    
    57.     sjmp $
    58.                
    59. ;==========================================================
    60.        
    61. ;=========================================================
    62. ; Sub routines for I2C communication (EEPROM)                      
    63. ;=========================================================
    64.  
    65. write_data:    
    66.                 acall eeprom_start
    67.                 mov a,#0a0h          
    68.                 acall send_data
    69.                 mov a,r4              ;location address
    70.                 acall send_data
    71.                 mov a,r5              ;data to be send
    72.                 lcall send_data
    73.              ;     acall eeprom_stop
    74.                    ret  
    75. ;=========================================================
    76. read_data:
    77.              
    78.                 acall eeprom_start
    79.                 mov a,#0a0h
    80.                 acall send_data
    81.                 mov a,r4          ;location address
    82.                 acall send_data
    83.                 acall eeprom_start
    84.                 mov a,#0a1h
    85.                 acall send_data
    86.                 acall get_data
    87.                 acall eeprom_stop
    88.                 ret
    89. ;=========================================================
    90. eeprom_start:  
    91.                 setb sda
    92.                 nop
    93.                 setb scl
    94.                 nop
    95.                 nop
    96.                 nop
    97.                 clr sda
    98.                 nop
    99.                 nop
    100.                 clr scl
    101.                 nop
    102.                 nop
    103.                  nop              
    104.                 ret
    105. ;=========================================================
    106. eeprom_stop:  
    107.                clr sda
    108.                nop
    109.                nop
    110.                nop
    111.                nop
    112.                nop
    113.                nop
    114.                setb scl
    115.                nop
    116.                nop
    117.                nop
    118.                nop
    119.                nop
    120.                nop
    121.                setb sda
    122.                nop
    123.                nop
    124.                nop
    125.                ret
    126. ;=========================================================
    127. send_data:     mov r7,#00h
    128.        senda:  rlc a
    129.                mov sda,c
    130.                acall clock
    131.                inc r7
    132.                cjne r7,#08,senda
    133.                setb sda
    134.                nop
    135.                nop
    136.                nop
    137.                setb scl    
    138.                jb sda, $
    139.                clr scl
    140.                nop
    141.                nop                        
    142.                nop
    143.                nop
    144.                nop
    145.                nop
    146.             ;  acall eeprom_delay
    147.                ret                                      
    148. ;=========================================================
    149. get_data:
    150.                mov r7,#00h
    151.        get:       setb sda
    152.                nop
    153.                setb scl
    154.                nop
    155.                nop
    156.                mov c,sda
    157.                   rlc a
    158.                inc r7
    159.                clr scl
    160.                nop
    161.                nop
    162.                nop
    163.                cjne r7,#08,get
    164.                mov r1,a
    165.                ret
    166. ;=========================================================
    167. clock :        setb scl
    168.                nop
    169.                nop
    170.                nop
    171.                nop
    172.                clr scl
    173.                nop
    174.                nop
    175.                nop
    176.                nop
    177.                nop
    178.                nop
    179.                ret
    180. ;=========================================================
    181. eeprom_delay :  mov r7,#16      ;delay of  4.9 msec
    182.        eepromd: mov r2,#0ffh
    183.                 djnz r2,$
    184.                 djnz r7,eepromd
    185.                 ret
    186. ;=====================================================    
    187. /*
    188.  ack:
    189.      setb sda
    190.     nop
    191.     setb scl
    192.      nop
    193.     nop
    194.     clr sda
    195.     nop
    196.     nop
    197.     clr scl
    198.      nop
    199.     nop
    200.     nop
    201.  ret
    202. ;=====================================================
    203.  no_ack:
    204.       clr sda
    205.      setb scl
    206.      nop
    207.      nop
    208.      setb sda
    209.      clr scl
    210.      nop
    211.      nop    
    212.      nop
    213.  ret   */
    214. ;=====================================================      
    215. end;
    If the above code is burned then the output is :
    Memory location 00 to 04 are written with '11' and the next function of writing the same value to mem location 05 doesn't work :confused: The led doesn't blink in this case. This shows the program is somewhere stuck inside the second function. So the only thing i can suspect is something is happening in my stop protocol.

    similarly if i do the below modifications in my 'main function'

    Code ( (Unknown Language)):
    1.  ;======================================================== Main Function
    2.  
    3. /*
    4.     mov r4,#00h                ;mem location
    5.     mov r5,#11h                ;data
    6.     lcall write_data    
    7.     mov a,#11h              ;data to be send
    8.     lcall send_data
    9.     mov a,#11h              ;data to be send
    10.     lcall send_data
    11.     mov a,#11h              ;data to be send
    12.     lcall send_data
    13.     mov a,#11h              ;data to be send
    14.     lcall send_data
    15.     acall eeprom_stop
    16.  
    17.     mov r4,#05h              ;mem location
    18.        mov r5,#22h              ;data
    19.     lcall write_data
    20.     acall eeprom_stop
    21.                                                         */
    22.                                            
    23.  
    24. readagain:
    25.     mov r4,#04h              ;mem location    
    26.     lcall read_data
    27.     cjne r1, #11h, readagain        
    28.  
    29.     clr led
    30.    
    31.     sjmp $
    32.                
    33. ;==========================================================
    34.  
    It reads perfectly and the led blinks.
    It shows me both read and write protocols are working smooth. But when there is a 'stop' function called then the following function doesn't seems to be working.

    Please help me out from this if any one of you could figure it out.

    Thank you "GetDeviceInfo" for your code. Even though its in C which i dont use, still i checked and found it matching to my code.

    Awaiting your responses. Thank you all for your patience and support.
     
  8. GetDeviceInfo

    Senior Member

    Jun 7, 2009
    1,571
    230
    our 'stops' are substantially different.
     
  9. hadeedunhaad

    Thread Starter New Member

    Apr 22, 2011
    24
    0
    where is it different ? i see them both implementing the following timing diagram for I2C communication.
    [​IMG]
    [​IMG]

    thank you
    [​IMG]
     
  10. hadeedunhaad

    Thread Starter New Member

    Apr 22, 2011
    24
    0
    alas ! the problem got solved, thank you friends for you support.:)

    FYI, following is the change which i made to my code.

    Code ( (Unknown Language)):
    1. send_data:  
    2.                mov b,a
    3.                mov r7,#00h
    4.      sends: rlc a
    5.                mov sda,c
    6.                acall clock
    7.                inc r7
    8.                cjne r7,#08,sends
    9.                acall ack
    10.                jnc tookof  
    11.                mov a,b
    12.                acall I2C_stop
    13.                acall I2C_start
    14.                sjmp send_data
    15.       tookof:
    16.                ret        
     
Loading...