Hello,
I am using the TMP112 sensor in combination with the MSP430G2553 and have troubles getting the right temperature data.
I am using the MSP DCO operating at 8 MHz which is also the SMCLK frequency. With a divider of 80, I get the I2C frequency of 100 kHz. The A0 Pin of the TMP112 is connected to ground, so that I have to address 1001000 = 0x48. I put those into the initI2C() function. My C-code looks as follows:
void initI2C()
{
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2 |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, I2C Mode, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 80; // fSCL = SMCLK/80 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x48; // Set slave address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
}
As the initial address pointer value is 00 and pointing to the temperature register, I'm guessing it should be sufficient to enter the receive mode and collect high- and lowbyte from the RXBUFFER. For debugging, I am using a UART communication with the terminal program HTerm to verify my results. This is done by using the function sendByte and should work properly, as it was tested with reference values.
void I2C_TMP112_read()
{
unsigned char temp;
UCB0CTL1 &= ~UCTR; // Master Receive Mode
UCB0CTL1 |= UCTXSTT; // send Start Condition
while (!(IFG2 & UCB0RXIFG)); // Loop until I2C STT is cleared, slave acknowledge was received and RXBUFFER is ready
temp = UCB0RXBUF;
sendByte(temp);
while (!(IFG2 & UCB0RXIFG)); // Loop until RXBUFFER ready
temp = UCB0RXBUF;
sendByte(temp);
sendByte('\n');
UCB0CTL1 |= UCTXSTP;
}
Now these are the results that I can see in HTerm:
11111111 01100000 00001010
Here, the last Byte 0x0A is correctly transmitted as the Linefeed byte '\n'. The problem is with the temperature data. Those values don't represent room temperature and I got the feeling that I was accessing the configuration register, although the values do not fit those of the initial configuration register after power up.
So I tried to set the address pointer manually to 00 with a second initialization function, so that the temperature register would be default for all readouts.
void I2C_TMP112_init()
{
UCB0CTL1 |= UCTR + UCTXSTT; // Master Transmit Mode
while (!(IFG2 & UCB0TXIFG));
UCB0TXBUF = 0x00;
UCB0CTL1 |= UCTXSTP;
}
But that didn't do the trick either. The following main function was used to get the results:
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
initClock();
initUART();
initI2C();
//I2C_TMP112_init();
__bis_SR_register(GIE);
while(1)
{
I2C_TMP112_read();
__delay_cycles(8000000);
}
}
Do you have any advice on how to solve this problem?