During the interfacing of MSP430 with the slave DS2764 (battery protection IC), the device is unable to send a START bit to the slave. The SCL and SDA lines are held line constantly but the SCL is pulled low after the Start condition execution step and it remains low.
Below is the code written for the same;
#include <msp430.h>
int i=0,mcnt=0,flag=0;
unsigned char Maddr= 0x0C ;
int a[2];
/*..............................................................................
// Transmit Initialization function
// arguments :
slave_add= This is the 7 bit slave address of DS2764
prescale = pass 0x12 as this argument for 100kHz clock
Hardware connections:
SDA - Pin 3.1 - Board pin number 34
SCL - Pin 3.2 - Board pin number 35
//............................................................................*/
void tx_init(unsigned char slave_add,unsigned char prescale)
{
P3SEL |= 0x06; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = prescale; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = slave_add; // Slave Address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCTXIE+UCRXIE; // Enable TX and RX interrupt
}
/*..............................................................................
// Read begin function
// arguments :
None. However, define Maddr as a gloabl unsigned char where Maddr= Memory address of DS to be read.
Also, make global int mcnt=0
Hardware connections:
SDA - Pin 3.1 - Board pin number 34
SCL - Pin 3.2 - Board pin number 35
//............................................................................*/
void read_begin()
{
while(UCB0CTL1 & UCTXSTP); //Ensure that the STOP condition got sent.
UCB0CTL1 |= UCTR + UCTXSTT; //Enable transmission and generate START condition.
mcnt=1; // To generate Maddr out on SDA line (inside interrupt)
}
void main()
{
WDTCTL=WDTPW+WDTHOLD;
float volt=0.0;
tx_init(0x34, 12);
a[0]=a[1]=0;
read_begin();
while(!flag);
// a[1] is Voltage LSB and a[0] is voltage MSB;
// store it in an integer called volt (defined above)
volt += (float)((long)(a[0] & 0x7F) << 3) * 0.00488;
volt += (float)(a[1] >> 5) * 0.00488;
//volt=volt*1000;
//printf("%d", volt); #FUC*_IAR
__no_operation();
}
//.............................................................................
// Interrupt vector for the USCI_B0 Module
//.............................................................................
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
switch(__even_in_range(UCB0IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: break; // Vector 6: STTIFG
case 8: break; // Vector 8: STPIFG
case 10: // Vector 10: RXIFG
if(i<3)
{
a[i] = UCB0RXBUF;
i++;
}
else
{
UCB0CTL1 |= UCTXSTP; //All Data received (2 bytes). STOP condition generated.
flag=1;
}
break;
case 12: // Vector 12: TXIFG
if(mcnt == 1) // To just send the Maddr to DS2764
{
UCB0CTL1 &= ~UCTR; // Shift to receive mode
UCB0CTL1 |= UCTXSTT; //Generate continuaous start condition for next start
UCB0TXBUF = Maddr; //send Maddr
mcnt=0;
}
break;
default: break;
}
}