Other Parts Discussed in Thread: MSP430FR2100
Tool/software: IAR Embedded
Hello,
I'm a beginner on MSP430 and programming, and need some help with a project of mine.
Project- To interface an external temperature sensor MCP9808 through I2C communication with MSP430FR4133 to get temperature value.
Connections
SDA- pin 5.2
SCL- pin 5.3
GND-GND
VDD- 3.3V
I have interfaced a temperature sensor MCP9808 with MSP430FR4133 through i2c communication. I am using the following code to read the temperature value from the sensor. I couldn't find the required results to get temperature value.
I am facing problem to get the desired results.
In MCP9808 data sheet in CONFIG Register part where I have to write
Addressbyte(0x30),Configuration pointer (0x01), MSB(0x00), LSB (0x08)
and read out Addressbyte(0x31), (0x00), (0x08) as a desired result but I am reading out Addressbyte(0x31), (0x00), (0x18), (0x01).
I have attached results below which are taken by logic analyzer. Any guidance to help me understand where I am doing mistake will be appreciated.
#define I2C__MSP430FR4133_H_
#include <MSP430.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "usci.h"
#define AMBIENT_TEMPERATURE 0x05
//#define Configuration_Reg 0x01
#define DEVICE_ID_REGISTER 0x04
#define MANUFACTURE_ID_REGISTER 0x0054
//#define AdressByte 0x30
uint16_t tlen = 0;
uint16_t rlen = 0;
int *tx = NULL;
int *rx = NULL;
uint8_t addr = 0x18;
// void *tx =(void *)0x01;
// void *rx =(void *)0x00;
volatile unsigned char RXData;
volatile unsigned char TXData;
long Temperature;
void Stop_WD (void);
uint16_t I2C_TempRead(void);
uint16_t I2C_readMode(void);
void delay_tick(uint16_t);
unsigned char Adressbyte[10];
unsigned char Transmit [10];
unsigned char Meas_Receive [10];
int main(void)
{
Stop_WD();
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
Set_I2C();
//Transmit [0] =0x30 & 0xFE;
Transmit [0] = 0x01;
Transmit [1] = 0x00;
Transmit [2]= 0x08;
Meas_Receive [0] = 0x07;
__bis_SR_register(GIE);
I2C_write(&Transmit[0],3,addr);
delay_tick(500);
Set_I2C();
I2C_write_read (&Transmit[0],1,&Meas_Receive [0],3,addr);
//I2C_write(&Transmit[0],1,addr);
//I2C_read(&Meas_Receive [0],2,addr);
//I2C_readMode();
//I2C_TempRead();
//
while (1)
{
__delay_cycles(2000);
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT; // I2C start condition
__bis_SR_register(LPM0_bits|GIE); // Enter LPM0 w/ interrupt
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: break; // Vector 0: No interrupts
case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG
case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG
UCB0CTL1 |= UCTXSTT; // resend start I2C start condition
break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
case USCI_I2C_UCSTPIFG: // Vector 8: STPIFG
TXData = 0;
UCB0IFG &= ~UCSTPIFG; // Clear stop condition int flag
break;
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3
case USCI_I2C_UCTXIFG3: break; // Vector 14: TXIFG3
case USCI_I2C_UCRXIFG2: break; // Vector 16: RXIFG2
case USCI_I2C_UCTXIFG2: break; // Vector 18: TXIFG2
case USCI_I2C_UCRXIFG1: break; // Vector 20: RXIFG1
case USCI_I2C_UCTXIFG1: // Vector 22: TXIFG1
// UCB0TXBUF = TXData++;
break;
case USCI_I2C_UCRXIFG0: // Vector 24: RXIFG0
RXData = UCB0RXBUF; // Get RX data
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
break;
case USCI_I2C_UCTXIFG0: break; // Vector 26: TXIFG0
case USCI_I2C_UCBCNTIFG: break; // Vector 28: BCNTIFG
case USCI_I2C_UCCLTOIFG: break; // Vector 30: clock low timeout
case USCI_I2C_UCBIT9IFG: break; // Vector 32: 9th bit
default: break;
}
}
void Stop_WD (void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
}
//
//
//void Device_ID(uint8_t device_reg)
//{
//
//}
//
//void Manufacture_ID(uint8_t manufacture_reg)
//{
//
//}
//
//void Ambient_Temp(uint8_t ambient_temp_reg)
//{
//
//}
uint16_t I2C_readMode(void)
{
uint8_t UpperByte = 0;
uint8_t LowerByte = 0;
uint16_t data = 0;
// UpperByte = i2c_read(); // READ 8 bits
////and Send ACK bit
//LowerByte = i2c_read(); // READ 8 bits
////and Send NAK bit
data = UpperByte<<8|LowerByte;
return data;
}
uint16_t I2C_TempRead(void)
{
uint8_t UpperByte = 0;
uint8_t LowerByte = 0;
uint16_t Temperature = 0;
//Convert the temperature data
//First Check flag bits
if ((UpperByte & 0x80) == 0x80)
{ //TA ³ TCRIT
}
if ((UpperByte & 0x40) == 0x40)
{ //TA > TUPPER
}
if ((UpperByte & 0x20) == 0x20)
{ //TA < TLOWER
}
UpperByte = UpperByte & 0x1F; //Clear flag bits
if ((UpperByte & 0x10) == 0x10)
{ //TA < 0°C
UpperByte = UpperByte & 0x0F; //Clear SIGN
Temperature = 256 - (UpperByte * 16 + LowerByte / 16);
}
else
{ //TA ³ 0°C
Temperature = (UpperByte * 16 + LowerByte / 16);
//Temperature = Ambient Temperature (°C)
}
return Temperature;
}
void delay_tick(uint16_t tick)
{
for (uint16_t i=0;i<tick; i++);
}
//----------------------------------------------I2C--------------------------------//
void Set_I2C(void)
{
P5SEL0 |= BIT2 | BIT3; // I2C pins
// Configure USCI_B0 for I2C mode
UCB0CTLW0 |= UCSWRST; // Software reset enabled
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync
UCB0CTLW1 |= UCASTP_2; // Automatic stop generated
UCB0BRW = 0x0008; // baudrate = SMCLK / 8
UCB0TBCNT = 0x07; // number of bytes to be received
UCB0I2CSA = 0x18; // Slave address is 0x18
UCB0CTL1 &= ~UCSWRST;
UCB0IE |= UCRXIE | UCNACKIE | UCBCNTIE ;
}
//------------------I2C_Master_write-------------------------------------------------//
uint32_t I2C_write(unsigned char* tx, uint32_t tlen,uint8_t addr)
{
uint32_t r_val = 0;
UCB0I2CSA = addr; // Assing slave address
while ((UCB0IFG & UCSTPIFG)); // Check if Stop condition on
UCB0CTL1 |= UCTR + UCTXSTT; // Start writing through I2C
while (!(UCB0IFG & UCTXIFG)); // Wait until TX buffer ready
for(uint32_t i = 0; i < tlen; i++)
{
UCB0TXBUF = *((uint8_t*)tx + i); // Write string in TX buffer of I2C
while (!(UCB0IFG & UCTXIFG)); // Wait until TX buffer ready
if( i == tlen - 1)
{ // If only one byte left to write
UCB0CTL1 |= UCTXSTP; // I2C stop condition
UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
}
r_val++; // Increment return value
}
return r_val;
}
//----------------I2C_MASTER_READ--------------------------------------------------------//
uint32_t I2C_read(unsigned char* rx, uint32_t rlen, uint8_t addr)
{
UCB0IFG &= ~UCSTPIFG;
uint32_t r_val = 0;
UCB0I2CSA = addr; // Assing slave address
if (rlen != 0)
{
while ((UCB0CTL1 & UCTXSTP)); // Check if Stop condition on
UCB0CTL1 &= ~UCTR; // Set writing bit in register to 0
UCB0CTL1 |= UCTXSTT; // Start reading through I2C
while (!(UCB0CTL1 & UCTXSTT)); // start condition is not sent
// only one byte
if (rlen == 1)
{
while (!(UCB0IFG & UCRXIFG)) // wait until start condition is sent
{
if((UCB0CTL1 & UCTXSTT)==0)
UCB0CTL1 |= UCTXSTP; // generate stop condition
}
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
*((uint8_t*)rx) = UCB0RXBUF;
return 1;
}
// multiple bytes
for (uint8_t i = 0; i < rlen-1; i++)
{
while (!(UCB0IFG & UCRXIFG)); // Wait until new data was written into RX buffer
*((uint8_t*)rx + i) = UCB0RXBUF; // Read RX buffer
r_val ++; // Increment return value
}
UCB0CTL1 |= UCTXSTP; // Generate Stop condition
while (UCB0CTL1 & UCTXSTP); // Wait untill its generated
*((uint8_t*)rx+rlen-1) = UCB0RXBUF; // Read last byte
}
return r_val++;
}
/*******************/
uint32_t I2C_write_read (unsigned char* tx,uint32_t tlen,unsigned char* rx, uint32_t rlen,uint8_t addr)
{
uint32_t r_val = 0;
UCB0I2CSA = addr; // Assing slave address
while ((UCB0IFG & UCSTPIFG)); // Check if Stop condition on
UCB0CTL1 |= UCTR + UCTXSTT; // Start writing through I2C
while (!(UCB0IFG & UCTXIFG)); // Wait until TX buffer ready
for(uint32_t i = 0; i < tlen; i++)
{
UCB0TXBUF = *((uint8_t*)tx + i); // Write string in TX buffer of I2C
while (!(UCB0IFG & UCTXIFG)); // Wait until TX buffer ready
if( i == tlen - 1)
{ // If only one byte left to write
UCB0CTL1 |= UCTXSTP; // I2C stop condition
UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
}
r_val++; // Increment return value
}
r_val = 0;
if (rlen != 0)
{
while ((UCB0CTL1 & UCTXSTP)); // Check if Stop condition on
UCB0CTL1 &= ~UCTR; // Set writing bit in register to 0
UCB0CTL1 |= UCTXSTT; // Start reading through I2C
while (!(UCB0CTL1 & UCTXSTT)); // start condition is not sent
// only one byte
if (rlen == 1)
{
while (!(UCB0IFG & UCRXIFG)) // wait until start condition is sent
{
if((UCB0CTL1 & UCTXSTT)==0)
UCB0CTL1 |= UCTXSTP; // generate stop condition
}
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
*((uint8_t*)rx) = UCB0RXBUF;
return 1;
}
// multiple bytes
for (uint8_t i = 0; i < rlen-1; i++)
{
while (!(UCB0IFG & UCRXIFG)); // Wait until new data was written into RX buffer
*((uint8_t*)rx + i) = UCB0RXBUF; // Read RX buffer
r_val ++; // Increment return value
}
UCB0CTL1 |= UCTXSTP; // Generate Stop condition
while (UCB0CTL1 & UCTXSTP); // Wait untill its generated
*((uint8_t*)rx+rlen-1) = UCB0RXBUF; // Read last byte
}
return r_val++;
}
Thank you!
Mr. Shetty
Student