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.

CCS/MSP430G2553: MSP430 I2C and UART not working together

Part Number: MSP430G2553

Tool/software: Code Composer Studio

Hello friends, I am trying to communicate the MSP430 with CI DS1307 (RTC) via I2C, and send their data via UART. But I can not read via I2C and send through the UART at the same time. I2C works normally without the UART, and the UART works normally without the I2C, but they do not work together.
 
This is my code:
 
#define SLA_ADR 0x68
unsigned char dados[8];
unsigned char control = 0;
int I2C_WRITE_READ = 1;                        //0 - IDLE; 1 - WRITING; 2 - READING
int I2C_STATE = 0;
int Num;
int new_hex;
int A;
int B;                          //{reset, segmin, hora, d_se, d_me,  mesano, confi}
unsigned char relogio_buffer[9] = {0x00, 0x30, 0x32, 0x21, 0x07, 0x05, 0x10, 0x18, 0x10};
unsigned char relogio_buffer_leitura[7] = {0, 0, 0, 0, 0, 0, 0};
struct time {
    unsigned short int milis;               //milisegundo
    unsigned char sec;                      //segundo
    unsigned char min;                      //minuto
    unsigned char hour;                     //hora
    unsigned char date;                     //data
    unsigned char day;                      //dia
    unsigned char mon;                      //mes
    unsigned char year;                     //ano
} relogio = {0,0,0,0,0,0,0,0};
  
int main(void)
{
    Clock_Config();
GPIO_Config();
    UART_Config();
    I2C_Config();
    __enable_interrupt();
 
    while(1)
    {
        //*****************************----------------------------***********************
        //*****************************-----------RTC--------------***********************
        //*****************************----------------------------***********************
 
        if(I2C_WRITE_READ == 0) I2C_WRITE_READ = 2;
 
        if((I2C_WRITE_READ == 2) && (I2C_STATE == 0))
        {
            I2C_STATE = 19;
            I2C_Read();
        }
        else if(I2C_STATE >= 19)
        {
            I2C_Read();
        }
        else if((I2C_STATE < 19) && ((I2C_WRITE_READ == 1) || (I2C_STATE > 0)))
        {
            I2C_Write();
        }
 
        //*****************************----------------------------***********************
        //*****************************----------------------------***********************
        //*****************************----------------------------***********************
    }
}
 
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
    if (IFG2 & UCB0TXIFG)
    {
        IFG2 &= ~UCB0TXIFG;
        I2C_STATE++;
    }
 
    if (IFG2 & UCB0RXIFG)
    {
        IFG2 &= ~UCB0RXIFG;
        if (I2C_STATE == 22)
        {
            relogio.sec = ((UCB0RXBUF & 0xF0) >> 0x04)*10;     //Read seconds
            relogio.sec += (UCB0RXBUF & 0x0F);
            IE2 |= UCA0TXIE;
            UCA0TXBUF = relogio.sec;
            I2C_STATE = 23;
        }
        else if (I2C_STATE == 24)
        {
            relogio.min = ((UCB0RXBUF & 0xF0) >> 0x04)*10;     //Read minutes
            relogio.min += (UCB0RXBUF & 0x0F);
            UCA0TXBUF = relogio.min;
            I2C_STATE = 25;
        }
        else if (I2C_STATE == 26)
        {
            relogio.hour = ((UCB0RXBUF & 0xF0) >> 0x04)*10;     //Read hours
            relogio.hour += (UCB0RXBUF & 0x0F);
            UCA0TXBUF = relogio.hour;
            I2C_STATE = 27;
        }
        else if (I2C_STATE == 28)
        {
            relogio.date = ((UCB0RXBUF & 0xF0) >> 0x04)*10;     //Read days
            relogio.date += (UCB0RXBUF & 0x0F);
            UCA0TXBUF = relogio.date;
            I2C_STATE = 29;
        }
        else if (I2C_STATE == 30)
        {
            relogio.day = ((UCB0RXBUF & 0xF0) >> 0x04)*10;     //Read dates
            relogio.day += (UCB0RXBUF & 0x0F);
            UCA0TXBUF = relogio.day;
            I2C_STATE = 31;
        }
        else if (I2C_STATE == 32)
        {
            relogio.mon = ((UCB0RXBUF & 0xF0) >> 0x04)*10;     //Read months
            relogio.mon += (UCB0RXBUF & 0x0F);
            UCA0TXBUF = relogio.mon;
            I2C_STATE = 33;
        }
        else if (I2C_STATE == 34)
        {
            relogio.year = ((UCB0RXBUF & 0xF0) >> 0x04)*10;     //Read years
            relogio.year += (UCB0RXBUF & 0x0F);
            UCA0TXBUF = relogio.year;
            I2C_STATE = 35;
        }
        else if (I2C_STATE == 36)
        {
            control = ((UCB0RXBUF & 0xF0) >> 0x04)*10;          //Read control
            control += (UCB0RXBUF & 0x0F);
            UCA0TXBUF = control;
            IE2 &= ~UCA0TXIE;
            I2C_STATE = 37;
        }
    }
}
void Clock_Config(void)
{
    WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
    if (CALBC1_16MHZ==0xFF)                   // If calibration constant erased
    {
        while(1);                             // do not load, trap CPU!!
    }
    DCOCTL = 0;                               // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_16MHZ;                   // Set DCO
    DCOCTL = CALDCO_16MHZ;
}
 
void GPIO_Config(void)
{
    P1DIR |= BIT0 + BIT6 + BIT7;
    P2DIR |= BIT0 + BIT1 + BIT3;
    P1REN |= BIT3 + BIT4;
    P1OUT |= BIT3 + BIT4 + BIT6 + BIT7;
    P1OUT &= ~BIT0;
}
void UART_Config(void)
{
    P1SEL |= BIT1 + BIT2;                     // P1.1 = RXD, P1.2=TXD
    P1SEL2 |= BIT1 + BIT2;                    // P1.1 = RXD, P1.2=TXD
    UCA0CTL1 |= UCSWRST;
    UCA0CTL0 |= UCMODE_0;
    UCA0CTL1 = UCSSEL_2 + UCSWRST;            // UCSSEL_2 = SMCLK; UCSWRST = Reset
    UCA0BR0 = 104;                            // 16MHz 9600
    UCA0BR1 = 0;                              // 16MHz 9600
    UCA0MCTL = UCBRF2 + UCBRF1 + UCOS16;      // Modulation UCBRSx = 0, UCBRFx = 3, UCOS16 = 1
    UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
    IE2 |= UCA0RXIE;
}
 
void I2C_Config(void)
{
    P1SEL |= BIT6 + BIT7;                   //BIT6 = SCL; BIT7 = SDA
    P1SEL2 |= BIT6 + BIT7;                  //BIT6 = SCL; BIT7 = SDA
    UCB0CTL1 |= UCSWRST;                    //Reset
    UCB0CTL0 |= UCMST + UCMODE_3 + UCSYNC;   //UCMST = Modo Master; UCMODE_3 = Modo I2C; UCSYNC = Modo Sincrono
    UCB0CTL1 = UCSSEL_2 + UCSWRST;          //UCSSEL_2 = SMCLK; UCSWRST = Reset
    UCB0BR0 = 160;                          //UCBR0 = 160
    UCB0BR1 = 0;                            //UCBR1 = 0; (UCBR0 + UCBR1*256) = prescaler
    UCB0I2COA = 0;                          //I2COA0 = 0; Endereco proprio
    UCB0I2CSA = SLA_ADR;                    //I2CSA = SLA_ADR
    UCB0CTL1 &= ~UCSWRST;                   //Unreset
    UCB0I2CIE |= UCSTTIE;
    IE2 |= UCB0TXIE + UCB0RXIE;             //UCB0TXIE = Habilita interrupcao TX I2C;  UCB0RXIE = Habilita interrupcao RX I2C
}
 
void I2C_Write(void)
{
    if (I2C_STATE == 0)
    {
        I2C_Config();
 
        UCB0I2CSA = SLA_ADR;                     //SLA_ADR = 0x68
        UCB0CTL0 &= ~UCSLA10;                    //UCSLA10 = Slave adress 7 bits
        UCB0CTL1 |= UCTR + UCTXSTT;              //UCTR = Modo transmissao; UCTXSTT = Transmite um start condition
        IFG2 &= ~(UCB0TXIFG);                    //Clear any pending interrupts
        IE2 |= UCB0TXIE;                         //Enable TX interrupt
        UCB0TXBUF = 0x00;
        I2C_STATE = 1;
    }
 
    else if (I2C_STATE == 2)
    {
        Num = relogio_buffer[1];
        A = Num/10;
        B = Num - (A*10);
        new_hex = A*16 + B;
        UCB0TXBUF = relogio_buffer[1];                    //Config seconds
        I2C_STATE = 3;
    }
 
    else if (I2C_STATE == 4)
    {
        Num = relogio_buffer[2];
        A = Num/10;
        B = Num - (A*10);
        new_hex = A*16 + B;
        UCB0TXBUF = relogio_buffer[2];                  //Config minutes
        I2C_STATE = 5;
    }
 
    else if (I2C_STATE == 6)
    {
        Num = relogio_buffer[3];
        A = Num/10;
        B = Num - (A*10);
        new_hex = A*16 + B;
        UCB0TXBUF = relogio_buffer[3];                    //Config hours
        I2C_STATE = 7;
    }
 
    else if (I2C_STATE == 8)
    {
        Num = relogio_buffer[4];
        A = Num/10;
        B = Num - (A*10);
        new_hex = A*16 + B;
        UCB0TXBUF = relogio_buffer[4];                    //Config dates
        I2C_STATE = 9;
    }
 
    else if (I2C_STATE == 10)
    {
        Num = relogio_buffer[5];
        A = Num/10;
        B = Num - (A*10);
        new_hex = A*16 + B;
        UCB0TXBUF = relogio_buffer[5];                    //Config days
        I2C_STATE = 11;
    }
 
    else if (I2C_STATE == 12)
    {
        Num = relogio_buffer[6];
        A = Num/10;
        B = Num - (A*10);
        new_hex = A*16 + B;
        UCB0TXBUF = relogio_buffer[6];                    //Config months
        I2C_STATE = 13;
    }
 
    else if (I2C_STATE == 14)
    {
        Num = relogio_buffer[7];
        A = Num/10;
        B = Num - (A*10);
        new_hex = A*16 + B;
        UCB0TXBUF = relogio_buffer[7];                    //Config years
        I2C_STATE = 15;
    }
 
    else if (I2C_STATE == 16)
    {
        UCB0TXBUF = 0x10;                       //Config control register
        I2C_STATE = 17;
    }
 
    else if (I2C_STATE == 18)
    {
        UCB0CTL1 |= UCTXNACK + UCTXSTP;          //UCTXNACK = Generate NACK; UCTXSTP = Generate STOP
        I2C_STATE = 0;
        if (I2C_WRITE_READ == 1)
        {
            I2C_WRITE_READ = 0;
        }
    }
}
 
void I2C_Read(void)
{
    if (I2C_STATE == 19)
    {
        I2C_Config();
 
        UCB0I2CSA = SLA_ADR;                     //SLA_ADR = 0x68
        UCB0CTL0 &= ~UCSLA10;                    //UCSLA10 = Slave adress 7 bits
        UCB0CTL1 |= UCTR + UCTXSTT;              //UCTR = Modo transmissao; UCTXSTT = Transmite um start condition
        IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);        //Clear any pending interrupts
        IE2 |= UCB0TXIE;                         //Enable TX interrupt
        UCB0TXBUF = 0x00;                        //Register address
        I2C_STATE = 20;
    }
    else if (I2C_STATE == 21)
    {
        UCB0I2CSA = SLA_ADR;                     //SLA_ADR = 0x68
        UCB0CTL0 &= ~UCSLA10;                    //UCSLA10 = Slave adress 7 bits
        UCB0CTL1 &= ~UCTR;                       //UCTR = Modo recepcao
        UCB0CTL1 |= UCTXSTT;                     //UCTXSTT = Transmite um start condition
        IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);        //Clear any pending interrupts
        IE2 |= UCB0RXIE;                         //Enable RX interrupt
        I2C_STATE = 22;
    }
    else if (I2C_STATE == 23) I2C_STATE = 24;     //Permite Read minutes
    else if (I2C_STATE == 25) I2C_STATE = 26;     //Permite Read hours
    else if (I2C_STATE == 27) I2C_STATE = 28;     //Permite Read days
    else if (I2C_STATE == 29) I2C_STATE = 30;     //Permite Read dates
    else if (I2C_STATE == 31) I2C_STATE = 32;     //Permite Read months
    else if (I2C_STATE == 33) I2C_STATE = 34;     //Permite Read years
    else if (I2C_STATE == 35)
    {
        UCB0CTL1 |= UCTXNACK + UCTXSTP;           //UCTXNACK = Generate NACK; UCTXSTP = Generate STOP
        I2C_STATE = 36;                           //Permite Read control
    }
    else if (I2C_STATE == 37)
    {
        UCB0CTL1 |= UCTXNACK + UCTXSTP;           //UCTXNACK = Generate NACK; UCTXSTP = Generate STOP
        IFG2 &= ~(UCB0RXIFG);
        IE2 &= ~(UCB0RXIE);
        I2C_STATE = 0;
    }
}

 
Can anybody help me?
  • What exactly do you mean with "do not work"? Which part of your code is not executed correctly?

    This state machine would be very hard to reverse engineer. Please explain how it is supposed to work.
  • Hello friend, thank you for replying. This problem:

    In this code I do the read / write on the RTC via I2C. Each state of the state machine represents the reading of a byte from the RTC. This can be seen in the I2C interrupt service (within if (IFG2 & UCB0RXIFG)).

    After I receive the byte from the RTC to the UCB0RXBUF, I convert the BCD format data and store it in the "relogio" variable.

    Then I get this variable and send it through UART, by UCA0TXBUF.

    And so the operation of the state machine would be: it writes the current date in the RTC (I2C_STATE = 0 to I2C_STATE = 18); and then read the RTC (I2C_STATE = 19 to I2C_STATE = 37); when it arrives in the last state, the state machine returns to I2C_STATE = 19 and stays forever just reading.

    However the write / read routine in the RTC via I2C does not work when I try to send the data through the UART.

    For example:

    If I comment the UART_Config () function on the main function, the write / read routine on the RTC works normally, as shown in the figure below:

    However if I uncomment the UART_Congif () function in the main function, the RTC stops working, and the I2C and UART stops working. The figure below shows the bus:

    Can you understand how I expect the code to work and what's happening?

  • Hi Luiz,
    In your code the RX interrupt service routine is missing
    #pragma vector = USCIAB0RX_VECTOR
    __interrupt void USCIAB0RX_ISR(void)
    {

    Regards,
    Stefan
  • Section 17.3.7.4 of the User's Guide says:

    USCI_Ax and USCI_Bx share the same interrupt vectors. In I²C mode the state change interrupt flags UCSTTIFG, UCSTPIFG, UCNACKIFG, UCALIFG from USCI_Bx and UCAxRXIFG from USCI_Ax are routed to one interrupt vector. The I²C transmit and receive interrupt flags UCBxTXIFG and UCBxRXIFG from USCI_Bx and UCAxTXIFG from USCI_Ax share another interrupt vector.

    So you have to use two interrupt handlers, and check and clear the correct interrupt flags in each one:

    #pragma vector = USCIAB0TX_VECTOR
    __interrupt void USCIAB0TX_ISR(void)
    {
        if (IFG2 & UCA0TXIFG)
            ...
        if (IFG2 & UCB0RXIFG)
            ...
        if (IFG2 & UCB0TXIFG)
            ...
    }
    
    #pragma vector = USCIAB0RX_VECTOR
    __interrupt void USCIAB0RX_ISR(void)
    {
        if (IFG2 & UCA0RXIFG)
            ...
        else
            // check I²C state changes
    }

  • Hi Stefan,

    Should I work with any I2C receiving code within the I2C receiving routine? That is, within the

    #pragma vector = USCIAB0RX_VECTOR
    __interrupt void USCIAB0RX_ISR (void)
    { ...

    Because in the code above, I'm working with the reception of the I2C data within the transmission routine, that is, within the

    #pragma vector = USCIAB0TX_VECTOR
    __interrupt void USCIAB0TX_ISR (void)
    {...

    What is the correct way to perform I2C communication with the RTC?
  • As written above, the I²C receive interrupt must be handled in the USCIAB0TX_ISR handler.
  • Hi Clemens,

    In my code I just monitored the UCB0TXIFG and UCB0RXIFG flags, I did not use the rest of the flags available in UCB0STAT. Maybe this is the problem. I could not understand the operation of this diagram:

    Could you translate this figure into a simple, generic code?

  • Hi Luiz,

    as Clemens showed above, there are two interrupt handler and for that you need to provide the functions:

    This one is called with the UART TX and the I2C RX and TX interrupt and needs to handle this functions
    #pragma vector = USCIAB0TX_VECTOR
    __interrupt void USCIAB0TX_ISR(void)
    {
        if (IFG2 & UCA0TXIFG)
            ...
        if (IFG2 & UCB0RXIFG)
            ...
        if (IFG2 & UCB0TXIFG)
            ...
    }

    This one is called with the UART RX and the I2C State interrupt and needs to handle this functions

    #pragma vector = USCIAB0RX_VECTOR 
    __interrupt void USCIAB0RX_ISR(void) 
    { 
     if (IFG2 & UCA0RXIFG) 
    ... else // check I²C state changes e.g. START and STOP bits }

    The reason why your code stuck currently is that you have enabled the UART RX interrupt but not handler for that provided. So the CPU jumps to an undefined location as soon as this interrupt happens.

    Regards,

     Stefan

  • Hello guys,

    I was able to run the RTC via I2C with the UART. I changed the code completely.

    Based on an example IT code for I2C communication. I changed the code for my case and added it to my UART interrupt routine.

    I do not read the RTC full time, only after sending the data to the UART.

    This is my new job code:

    #include <msp430g2553.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    #define SLAVE_ADDR  0x68
    #define CMD_TYPE_2_MASTER 5
    #define TYPE_1_LENGTH 6
    #define TYPE_2_LENGTH 8
    #define MAX_BUFFER_SIZE 20
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {0x30, 0x32, 0x21, 0x07, 0x17, 0x10, 0x18, 0x10};
    uint8_t SlaveType2 [TYPE_1_LENGTH] = {0};
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITHC_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    I2C_Mode MasterMode = IDLE_MODE;
    
    uint8_t TransmitRegAddr = 0;
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    void initClockTo16MHz(void);
    void GPIO_Config(void);
    void I2C_Config(void);
    void UART_Config(void);
    
    long int cont = 0;
    int FLAG = 0;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;
        initClockTo16MHz();
        GPIO_Config();
        UART_Config();
        I2C_Config();
    
        IFG2 &= ~UCA0TXIFG;
        I2C_Master_WriteReg(SLAVE_ADDR, 0x00, MasterType2, TYPE_2_LENGTH);
    
        while(1)
        {
            if ((MasterMode == IDLE_MODE) & (FLAG == 0))
            {
                I2C_Master_ReadReg(SLAVE_ADDR, 0x00, TYPE_2_LENGTH);
                CopyArray(ReceiveBuffer, SlaveType2, TYPE_1_LENGTH);
                FLAG = 1;
            }
            if ((MasterMode == IDLE_MODE) & (cont >= 65530) & (FLAG == 1))
            {
                FLAG = 2;
                RXByteCtr = 0;
                IFG2 |= UCA0TXIFG;
                IE2 |= UCA0TXIE;
            }
            if ((MasterMode == IDLE_MODE) & (FLAG == 3))
            {
                I2C_Master_ReadReg(SLAVE_ADDR, 0x00, TYPE_2_LENGTH);
                CopyArray(ReceiveBuffer, SlaveType2, TYPE_1_LENGTH);
                FLAG = 1;
                cont = 0;
            }
            if (cont < 65530) cont++;
        }
    }
    
    #pragma vector = USCIAB0TX_VECTOR
    __interrupt void USCIAB0TX_ISR(void)
    {
        if (IFG2 & UCA0TXIFG)
        {
            if (RXByteCtr < 7 )
                UCA0TXBUF = ReceiveBuffer[RXByteCtr];
            else
            {
                FLAG = 3;
                IFG2 &= ~UCA0TXIFG;
                IE2 &= ~UCA0TXIE;
            }
            RXByteCtr++;
        }
        if (IFG2 & UCB0RXIFG)                 // Receive Data Interrupt
        {
          uint8_t rx_val = UCB0RXBUF;
    
          if (RXByteCtr)
          {
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
          }
    
          if (RXByteCtr == 1)
          {
              UCB0CTL1 |= UCTXSTP;
          }
          else if (RXByteCtr == 0)
          {
              IE2 &= ~UCB0RXIE;
              MasterMode = IDLE_MODE;
              __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
          }
        }
        else if (IFG2 & UCB0TXIFG)            // Transmit Data Interrupt
        {
          switch (MasterMode)
          {
              case TX_REG_ADDRESS_MODE:
                  UCB0TXBUF = TransmitRegAddr;
                  if (RXByteCtr)
                      MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                  else
                      MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  break;
    
              case SWITCH_TO_RX_MODE:
                  IE2 |= UCB0RXIE;              // Enable RX interrupt
                  IE2 &= ~UCB0TXIE;             // Disable TX interrupt
                  UCB0CTL1 &= ~UCTR;            // Switch to receiver
                  MasterMode = RX_DATA_MODE;    // State state is to receive data
                  UCB0CTL1 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      if ((UCB0CTL1 & UCTXSTT) == 0)
                          UCB0CTL1 |= UCTXSTP;      // Send stop condition
                  }
                  break;
    
              case TX_DATA_MODE:
                  if (TXByteCtr)
                  {
                      UCB0TXBUF = TransmitBuffer[TransmitIndex++];
                      TXByteCtr--;
                  }
                  else
                  {
                      //Done with transmission
                      UCB0CTL1 |= UCTXSTP;     // Send stop condition
                      MasterMode = IDLE_MODE;
                      IE2 &= ~UCB0TXIE;                       // disable TX interrupt
                      __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
                  break;
    
              default:
                  __no_operation();
                  break;
          }
        }
    }
    
    #pragma vector = USCIAB0RX_VECTOR
    __interrupt void USCIAB0RX_ISR(void)
    {
        if (IFG2 & UCA0RXIFG)
        {
            IFG2 &= ~UCA0RXIFG;
            char A = UCA0RXBUF;
            if (A == 'A')
                P1OUT ^= BIT0;
        }
        if (UCB0STAT & UCNACKIFG)
        {
            UCB0STAT &= ~UCNACKIFG;             // Clear NACK Flags
        }
        if (UCB0STAT & UCSTPIFG)                        //Stop or NACK Interrupt
        {
            UCB0STAT &=
                ~(UCSTTIFG + UCSTPIFG + UCNACKIFG);     //Clear START/STOP/NACK Flags
        }
        if (UCB0STAT & UCSTTIFG)
        {
            UCB0STAT &= ~(UCSTTIFG);                    //Clear START Flags
        }
    }
    
    I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
    {
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
        RXByteCtr = count;
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        UCB0I2CSA = dev_addr;
        IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);       // Clear any pending interrupts
        IE2 &= ~UCB0RXIE;                       // Disable RX interrupt
        IE2 |= UCB0TXIE;                        // Enable TX interrupt
    
        UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(CPUOFF + GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = reg_addr;
    
        CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        UCB0I2CSA = dev_addr;
        IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);       // Clear any pending interrupts
        IE2 &= ~UCB0RXIE;                       // Disable RX interrupt
        IE2 |= UCB0TXIE;                        // Enable TX interrupt
    
        UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(CPUOFF + GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    void initClockTo16MHz()
    {
        if (CALBC1_16MHZ==0xFF)                  // If calibration constant erased
        {
            while(1);                               // do not load, trap CPU!!
        }
        DCOCTL = 0;                               // Select lowest DCOx and MODx settings
        BCSCTL1 = CALBC1_16MHZ;                    // Set DCO
        DCOCTL = CALDCO_16MHZ;
    }
    
    void GPIO_Config()
    {
        P1DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4;
        P1OUT &= ~(BIT0 + BIT1 + BIT2 + BIT3 + BIT4);
    
        P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
        P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
    }
    
    void I2C_Config()
    {
        UCB0CTL1 |= UCSWRST;                      // Enable SW reset
        UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
        UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
        UCB0BR0 = 160;                            // fSCL = SMCLK/160 = ~100kHz
        UCB0BR1 = 0;
        UCB0I2CSA = SLAVE_ADDR;                   // Slave Address
        UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
        UCB0I2CIE |= UCNACKIE;
    }
    void UART_Config(void)
    {
        P1SEL |= BIT1 + BIT2;                     // P1.1 = RXD, P1.2=TXD
        P1SEL2 |= BIT1 + BIT2;                    // P1.1 = RXD, P1.2=TXD
        UCA0CTL1 |= UCSWRST;
        UCA0CTL0 |= UCMODE_0;
        UCA0CTL1 = UCSSEL_2 + UCSWRST;            // UCSSEL_2 = SMCLK; UCSWRST = Reset
        UCA0BR0 = 104;                            // 16MHz 9600
        UCA0BR1 = 0;                              // 16MHz 9600
        UCA0MCTL |= UCBRF2 + UCBRF1 + UCOS16;      // Modulation UCBRSx = 0, UCBRFx = 3, UCOS16 = 1
        UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
        IE2 |= UCA0RXIE;
    }
    

    These are the I2C bus signals:

    And these are the signs read on the PC (the print screen was not taken at the same time):

    Thank you very much for your support!

**Attention** This is a public forum