Microcontroller – MSP430 I2C No ACK Send Over Bus

busi2cmicrocontrollermsp430serial-bus

I'm trying to get an I2C communication with an MSP430 (MSP430G2231) working. This is the first time I'm using a MSP430 for I2C and not sure if I'm doing everything correctly.

I have a Slave connected to SDA/SCL line of the Microcontroller with the Address: 0xE0 (the last Bit of the address is the Write Bit which needs to be set to 0). When monitoring the I2C bus with a logic analyzer I don't get any response from the slave to the send address – attached a picture of the bus communication. Are there any obvious errors in my code? Thanks a lot!

I2C Bus receiving Slave Address NACK

#include <msp430g2231.h>
#include <stdio.h>
#include <stdint.h>

    
void main(void) {
    WDTCTL = WDTPW + WDTHOLD;                                                   //disable watchdog timer
    

    
    //I2C init
    USICTL0 |= USIPE7 + USIPE6 + USIMST + USIOE + USISWRST;                     
    USICTL1 = USII2C;                                                           
    USICKCTL = USIDIV_7 + USISSEL_2 + USICKPL;                                 

    USICNT |= USIIFGCC;                                                         
    USICTL0 &= ~USISWRST;                                                      
    USICTL1 &= ~USIIFG;                                                                   
    
    while(1)
    {
        //Start Condition
        USISRL = 0x00;                                                              
        USICTL0 |= USIGE + USIOE;                                                   
        USICTL0 &= ~USIGE;
        
        //Send Data
        USISRL = 0xE0;                                                         
        USICTL0 |= USIOE;                                                           
        USICNT = 0x08;
        while((USICTL1 & USIIFG) != 0x01);                                          
        
        //Read Ack Bit
        USICTL0 &= ~USIOE;       
        USICNT |= 0x01;          
        USICTL0 |= USIOE;        
        
        //Stop
        USICTL0 |= USIOE;
        USISRL = 0x00;                                                              
        USICNT = 1;
        while((USICTL1 & USIIFG) != 0x01);                                          
      
        USISRL = 0xFF;                                                             
        USICTL0 |= USIGE;
        USICTL0 &= ~(USIGE+USIOE);
        
        for(delay=0; delay<100; delay++);
    }
}

.-.-
Update:

I have changed the section for the ACK Reading to the following code and getting now still no ACK from the slave (see attatched second image):

//Read Ack Bit
USICTL0 &= ~USIOE;       
USICNT = 0x01;
USICTL0 |= USIOE;          
while((USICTL1 & USIIFG) != 0x01);
ack_flag = USISRL;

Second updated I2C communication

Best Answer

USICNT |= 0x01;

The previous value of this register is 8. This results in a value of 9. To read one bit, just set the register to 1.

Section 14.2.4.3 of the User's Guide says:

To receive the I2C acknowledgment bit, the USIOE bit is cleared with software and USICNTx is loaded with 1. This clears USIIFG and one bit is received into USISRL. When USIIFG becomes set again, the LSB of USISRL is the received acknowledge bit and can be tested in software.

Your "Read Ack Bit" code does not wait for USIIFG.