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.
Hello!
I've deliberately named my question like that - I know that it's already been asked but the answers don't help me at all.
I have a custom board with MSP430G2553 and an I2C real-time clock M41T81S. I program it through the MSP-EXP430G2 launch pad. I use TEST & RST (pin 16, 17) & GND for programming. I have NO pull-ups. I use the internal ones. I use external Vdd.
My communication is stuck at while(UCB0CTL1 & UCTXSTT){ } and doesn't go on. Can please someone give me any ideas? Here's the code:
#include <msp430.h> int main(void) { WDTCTL = WDTPW + WDTHOLD; // Set DCO to 16MHz BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; BCSCTL2 &= ~SELS; //SMCLK = DCOCLK P1SEL |= 0xC0; P1SEL2|= 0xC0; P1REN |= 0xC0; P1OUT |= 0xC0; UCB0CTL1 |= UCSWRST; UCB0CTL0 = UCMST+UCMODE_3+UCSYNC; UCB0CTL1 = UCSSEL_2+UCSWRST; UCB0BR0 = 160; // fSCL = SMCLK/160 = ~100kbps UCB0BR1 = 0; UCB0I2CSA = 0x68; UCB0CTL1 &= ~UCSWRST; while (1) { UCB0CTL1 |= UCTR; UCB0CTL1 |= UCTXSTT; while (UCB0CTL1 & UCTXSTT){ } UCB0TXBUF = 0x02; while(IFG2 & UCB0TXIFG){ } UCB0CTL1 |= UCTXSTP; while (UCB0CTL1 & UCTXSTT){ } } }
Thanks in advance!
I got it working finally! IF YOU PLAN to use the polling method for I2C I advice you to do the following:
- Before the transmission is started wait a huge amount of time because the slave IC might not initialize as fast as the MCU
- When you develop your I2C code POWER-CYCLE the board because the slave I2C may crash and hold the lines low or something like that (during the programming of the MSP430 the I2C lines are sometimes toggling!)
- DO NOT use the internal pull-ups when using the I2C module ... solder external pull-ups (in my case - 3k3)
- DO NOT wait for the UCTXSTT bit to be cleared. Use the UCB0TXIFG flag instead.
Here is my working code:
#include <msp430.h> int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer // Set DCO to 16MHz BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; //SMCLK = DCOCLK BCSCTL2 &= ~SELS; P1SEL |= 0xC0; // Assign I2C pins to USCI_B0 P1SEL2|= 0xC0; // Assign I2C pins to USCI_B0 //P1REN |= 0xC0; //DO NOT USE //P1OUT |= 0xC0; //DO NOT USE UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC; // I2C Master, synchronous mode UCB0CTL1 |= UCSSEL_2; // Use SMCLK UCB0BR0 = 160; // fSCL = SMCLK/160 = ~100kbps UCB0BR1 = 0; UCB0I2CSA = 0x68; // Set slave address IFG2 &= ~UCB0TXIFG; UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation __delay_cycles(500000); //Wait for slave to initialize while (1) { while (UCB0CTL1 & UCTXSTP); UCB0CTL1 |= UCTR + UCTXSTT; //while (UCB0CTL1 & UCTXSTT); //DO NOT USE while(!(IFG2 & UCB0TXIFG)){ } IFG2 &= ~UCB0TXIFG; UCB0TXBUF = 0x02; while(!(IFG2 & UCB0TXIFG)){ } IFG2 &= ~UCB0TXIFG; UCB0CTL1 |= UCTXSTP; } }
**Attention** This is a public forum