This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

communication problem with 24lc64 and MSP430f2274

Other Parts Discussed in Thread: MSP430F2112

hi

 

i guess i am a little fresher in i2C i am trying to write and read data form the 24LC64 serial eeprom using msp430f2274 USIC module for the start condition i am able to get the ACK but after that i am trying to send the MSB of the address as per the datasheet of the eeprom i am not getting the ACK signal.

 

The main problem seems to be that i am unable to generate the 9th clock pulse that is required for the slave device to generate an ACk . pls correct the code i need to write only 10 bytes of data and i need to read it back

 

#include "msp430F2274.h"


void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x01;                            // P1.0 output
  P3SEL |= 0x06;                            // Assign I2C pins to USCI_B0
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
  UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
  UCB0BR1 = 0;
  UCB0I2CSA = 0x50;                         // Set slave address
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
//  IE2 |= UCB0TXIE;                          // Enable RX interrupt

{
   UCB0CTL1 |= UCTR + UCTXSTT;  // I2C Start Condition in master transmitter mode
   while (UCTXSTT==1);          // For reading the specified register
   UCB0TXBUF = 0x00;
   while (UCTXSTT==1);
   UCB0TXBUF = 0x02;
   while (UCTXSTT==1);
   UCB0CTL1 &= ~UCTXSTP;

 
}

}

  • First, UCTXSTT is a constant. So UCTXSTT is always eitehr true or false (I think it is false, since UCSTT is a constnt <> 1).
    The check would be
    while(UCB0CTL1 & UCTXSTT);
    Which is true (and loops) as ong as the UCTXSTT bit in UCB0CTL1 register is set.

    After this point, UCTXSTT remains clear until you set it again amnually. However, eithe rthe slave has reponded (ACK), or not (NACK). If the slave has not responded, UCNACKIFG bit is set in UCB0STAT, or the USCI waits for you to stuff something to send into UCB0TXBUF before it concludes the ACK cycle and continues with the transmission.
    However, you can already write the first byte to TXBUF once you have set UCTXSTT (as indicated by UCTXIFG which is set imemdiately when you set UCTXSTT to indicate that TXBUF is ready for a byte). In case of a slave NACK, the content of TXBUF is discarded then.

    To send additional bytes, you'll have to check for the UCB0TXIFG bit in IFG2 register

    while(!(IGG2&UCB=TXIFG));

    After this wait, you can stuff hte next byte to TXBUF or set UCTXSTP to end the transmission.

    Ther eis a nice, large, detailed diagram in the 2x family users guide, USCI I2C section, that shows the whole flow.

  • hi thanks for the reply i have managed to write the data successfully  but while reading in a loop i am not able to read the data \`s correctly is there any sample code for the same actually i am facing the same problem in RTC as well using I2C

  • vijayanarayana ramamoorthy said:
    i have managed to write the data successfully  but while reading in a loop i am not able to read the datas correctly

    Then there might be a quirk in your program flow.
    If you post your new code, I'll take a look at it.

  •  

     

    #include "msp430f2112.h"

    void RTC_INI();

    int RTC_READ(int l);

    int RTC_write (int l);

    int LCD_INI();

    int LCD_clr();

    int LCD_Write(int k);

    int BCDTOASCII(int e);

    int BCDTOASCIIMSB(int e);

    int  Year =  0x04 ;

    int main( void )

    {

     

      // Stop watchdog timer to prevent time out reset

      WDTCTL = WDTPW + WDTHOLD;

      BCSCTL1 = CALBC1_1MHZ; 

      DCOCTL = CALDCO_1MHZ;

      P1DIR |=0XFF; 

      P3SEL |= 0x06;

      LCD_INI(); 

      RTC_INI();

     int e=0,k=0,Year_temp=0,month_temp=0,Date_temp=0,temp_sec=0,temp_minutes = 0,temp_Hours =0 ;

     int temp_data=0;

     while(1)

    {  

      UCB0CTL1 |= UCTR + UCTXSTT;  // I2C Start Condition in master transmitter mode

       while (UCTXSTT==1);          // For reading the specified register

       while(!(IFG2&0x08));

       //IFG2 &=~UCB0TXIFG;  

       UCB0TXBUF =0x00; 

      while(!(IFG2&0x08));

         int i=0;

         while(i <=100)

      {

       i++;

      }

       UCB0CTL1 &= ~UCTR;           //I2C Start Condition in master recediver mode

      UCB0CTL1 |= UCTXSTT;         // For reading the specified register

       while(!(IFG2&0x04));

        temp_sec=UCB0RXBUF;   

          while(!(IFG2&0x04));

       temp_minutes =UCB0RXBUF;

        while(!(IFG2&0x04));

       temp_Hours =UCB0RXBUF;

        while(!(IFG2&0x04));

       Date_temp =UCB0RXBUF; 

        while(!(IFG2&0x04));

        month_temp =UCB0RXBUF;

         while(!(IFG2&0x04));

         UCB0CTL1 |= UCTXNACK;  

         UCB0CTL1 |=UCTXSTP;

         Year_temp =UCB0RXBUF;

     

       ///////////////////////////////////////////////////////////////////////

       temp_data = temp_sec ;

       temp_data = (temp_data & 0xF0);

       temp_data = ((temp_data >> 4)| 0x30);

       k = temp_data;

       LCD_Write(k);

       e = temp_sec;

       k = ((e & 0x0f) | 0x30);

       LCD_Write(k);

       k= '-';

       LCD_Write(k);

       ////////////////////////////////////////////

       temp_data = temp_minutes;

       temp_data = (temp_data & 0xF0);

       temp_data = ((temp_data >> 4)| 0x30);

       k = temp_data;

       LCD_Write(k);

       e = temp_minutes;

       k = ((e & 0x0f) | 0x30);

       LCD_Write(k);

       LCD_clr();

       i=0;

         while(i <=10000)

      {

       i++;

      }

     }

    return (0);

    }

     

    hi this is the code i have written for the RTC it is just reading if this goes correct  then i think i can suicessufully complete the EEProm as well

  • vijayanarayana ramamoorthy said:
     while (UCTXSTT==1);          // For reading the specified register


    This is still nonsense. UCTXSTT is a constant and always has the value of 0x02.
    What you mean is
    while (UCB0CTL1&UCTXSTT);
    which is identical to (UCB0CTL&UCTXSTT!=0) and has the same effect as (UCB0CTL1&UCTXSTT == UCTXSTT) or (UCB0CTL1&UCTXSTT==0x02).

    vijayanarayana ramamoorthy said:
       while(!(IFG2&0x08)); (first occurrence)


    This is pointless. After UCTXSTT was set, this bit is automatically set too. And after has been cleared (UCB0CTL1 no longer has the UCTXSTT bit set), it is either still set (if you didn't write anything to UCB0TXBUF) or the slave was not answering and it has been cleared and will never be set again (but UCNACKIFG in UCB0STAT has been set)

    If you want to send only one byte, there is no need to wait for TXIFG too. Just clear UCTR and set UCTXSTT right after you wrote to TXBUF. As soon as the byte has been sent, a repeated start condition will be generated. You can proceed right away. Of course if you want to send more than one byte, you'll have to wait for TXIFG before you write the next byte to TXBUF.

    One thing I noticed, you declare your temps as ints, but TXBUF/RXBUF is for bytes only (unsigned char). Just a minor issue (wasted ram and speed).

    Other than that, the code looks like it should work.

    If it doesn't, you should exactly write what hapens (what bytes do you receive, or does it hang somewhere)

    One more hint: on some RTCs (e.g. the PCF8583) it is necessary to latch teh registers before readign them. So you won't have the effect of erroneously reading 1:59  because it was 0:59 when you read the seconds and 1:00 when you read the minutes (applies to everything else too, date, hours)

     

  • hi ,

     

    i have managed to read and write the 24LC 64  correctly i have a small issue some times in the intial read the SDA line is held low will addressing the salve after that , there is no data transfer even after  the power is reset ,  but when the sda line is removed and connected (with power on )  the communication becomes normal every read and write cycle is working perfectly  untill the power is reset . I dont understand weather this is the issue with the hardware i have built or some issue in the code .

     

    and one more thing i have manged to read the RTC correctly i am trying to write to the RTC as off  now any hints for writing into the rtc 

     

    with regards

    Vijay

  • vijayanarayana ramamoorthy said:
    i have a small issue some times in the intial read the SDA line is held low


    It is possible that the port pin init causes teh slave to erroneously detect a start condition, messing up the bus logic.
    Normally, even if this happens, thsi should be fixed after at most two attempts to address the slave (with start and stop condition).
    However, some poorly implemented slaves have their port logic lock-up if the lines have unintended transitions after power-up. It shouldn't survive a power cycle.

    Also, some slaves need a certain startup time before they can be addressed, and will hold SCL down if being addressed too soon. They should release SCL once ready. But again, some poorly designed slaves might lock-up.

    vijayanarayana ramamoorthy said:
    I dont understand weather this is the issue with the hardware i have built or some issue in the code .

    Both possible. I didn't see anything obvious in the code, but maybe there are issues with the port-init sequence as well as the speed in wich your aplicaiton starts up (but sicne yo're not using any crystal, the startup speed should be nearly identical all the time).

    vijayanarayana ramamoorthy said:
    i have manged to read the RTC correctly i am trying to write to the RTC as off  now any hints for writing into the rtc 

    If you tell which one it is...

**Attention** This is a public forum