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.

Problem With Interfacing MSP430F2616 with DS1307

Other Parts Discussed in Thread: MSP430F2616

Dear All,

I am trying to interface RTC DS1307 with MSP430F2616. 

But iam getting a problem that i am unable to get the response from DS1307 using I2C Bit-Bang method and i think there is a problem with that code. Please help me regarding sorting out this issue.

 

For your reference i am attaching my code below. Also I would like to say I am running my Controller with 4Mhz Clock. I am using Port3.1 and port3.2 for SDA and SCl line respectively.

#include "UART_Init.h"
#include "I2C_master.h"

#define I2C_MASTER_REN P3REN
#define I2C_MASTER_DIR P3DIR
#define I2C_MASTER_OUT P3OUT
#define I2C_MASTER_IN  P3IN
//port pins
#define I2C_MASTER_SCL BIT2
#define I2C_MASTER_SDA BIT1
#define ACK		1
#define NO_ACK	0
#define SLAVE	0xD0
#define WRITE   0x00
#define READ    0x01
#define ERR_ACK 0x01
//-------------------------------
// start I2C
//-------------------------------
void Start(void)
{
    I2C_MASTER_DIR|= I2C_MASTER_SDA;
	I2C_MASTER_DIR|= I2C_MASTER_SCL;
	I2C_MASTER_OUT|= I2C_MASTER_SDA;
	I2C_MASTER_OUT|= I2C_MASTER_SCL;
//	delay_us(2);
	I2C_MASTER_OUT&= ~I2C_MASTER_SDA;
//	delay_us(2);
	I2C_MASTER_OUT&= ~I2C_MASTER_SCL;
//	delay_us(2);
}

//-------------------------------
// stop I2C
//-------------------------------
void Stop(void)
{
	I2C_MASTER_OUT&= ~I2C_MASTER_SDA;	    	
//	delay_us(2);
	I2C_MASTER_OUT|= I2C_MASTER_SCL;
//	delay_us(2);
	I2C_MASTER_OUT|= I2C_MASTER_SDA;	
}

//-------------------------------
// Write I2C
//-------------------------------
void WriteI2C(unsigned char Data)
{ 
	uint8_t i = 0;   
	for (i=0;i<8;i++)
	{
		if(Data & 0x80)
			I2C_MASTER_OUT|= I2C_MASTER_SDA;
		else
			I2C_MASTER_OUT&= ~I2C_MASTER_SDA;	
        I2C_MASTER_OUT|= I2C_MASTER_SCL;
        I2C_MASTER_OUT&= ~I2C_MASTER_SCL;
		Data<<=1;
	}
	I2C_MASTER_OUT|= I2C_MASTER_SCL;
	delay_us(2);
    I2C_MASTER_OUT&= ~I2C_MASTER_SCL;
}

//-------------------------------
// Read I2C
//-------------------------------
unsigned char ReadI2C(uint8_t ACK_Bit)
{
    uint8_t i = 0;
    unsigned char Data=0;
	I2C_MASTER_OUT&= ~I2C_MASTER_SDA;
    I2C_MASTER_DIR&= ~I2C_MASTER_SDA;
	for (i=0;i<8;i++)
	{
		I2C_MASTER_OUT|= I2C_MASTER_SCL;		
//		Data<<= 1;
		if( I2C_MASTER_IN & I2C_MASTER_SDA )
			Data|= (0x01 << i);
		else
			Data|= (0x00 << i);
		I2C_MASTER_OUT&= ~I2C_MASTER_SCL;
//		delay_us(2);
	}
    I2C_MASTER_DIR|= I2C_MASTER_SDA;
 	if (ACK_Bit == 1)
		I2C_MASTER_OUT&= ~I2C_MASTER_SDA; // Send ACK		
	else		
		I2C_MASTER_OUT|= I2C_MASTER_SDA; // Send NO ACK				

//	delay_us(2);
	I2C_MASTER_OUT|= I2C_MASTER_SCL;
//	delay_us(2);
	I2C_MASTER_OUT&= ~I2C_MASTER_SCL;
	
	return Data;
}

//-------------------------------
// Read 1 byte form I2C
//-------------------------------
unsigned char ReadBYTE(unsigned char Addr)
{
   	unsigned char Data;
	Start();
	WriteI2C(0xD0);
	WriteI2C(Addr);
	Start();
	WriteI2C(0xD1);
	Data = ReadI2C(NO_ACK);
	Stop();
   	return(Data);
}

//-------------------------------
// Write 1 byte to I2C
//-------------------------------
void WriteBYTE(unsigned char Addr,unsigned char Data)
{
	Start();
	WriteI2C(0xD0);
	WriteI2C(Addr);
	WriteI2C(Data);
	Stop();	
}

//-------------------------------
// Read RTC (all real time)
//-------------------------------
void ReadRTC(unsigned char * buff)
{
	Start();
	WriteI2C(0xD0);
	WriteI2C(0x00);
	WriteI2C(0x0F);
	delay_ms(2);
	Start();
	WriteI2C(0xD1);	
	*(buff+0)=ReadI2C(ACK);	// Second
//	*(buff+1)=ReadI2C(ACK);	// Minute
//	*(buff+2)=ReadI2C(ACK);	// hour
//	*(buff+3)=ReadI2C(ACK);	// Day
//	*(buff+4)=ReadI2C(ACK);	// date
//	*(buff+5)=ReadI2C(ACK);	// month
//	*(buff+6)=ReadI2C(NO_ACK);	// year
	Stop();		
}

//-------------------------------
// Write RTC
//-------------------------------
void WriteRTC(unsigned char *buff)
{

	Start();
	WriteI2C(0xD0);
	WriteI2C(0x00);	
	WriteI2C(*(buff+0));	
	WriteI2C(*(buff+1));
	WriteI2C(*(buff+2));
	WriteI2C(*(buff+3));
	WriteI2C(*(buff+4));
	WriteI2C(*(buff+5));
	WriteI2C(*(buff+6));	
	Stop();	
}

 

Thank you,

Regards,

Shravan Kumar

  • The start and stop functions are violating the I2C specs without any delays.

    The DS1307 is specified for the original I2C clock specification of at most 100kHz I2C clock. all hold times in the datasheet are >4.7µs.

    So in all your functions, you're simply way too fast for the slave device. It won't recognize whatever you do on the bus.

    To be on the safe side while you're testing your code, add delays which drop the I2C frequency down to 10kHz unless you know that your timebase for the delays is working.
    This means, adding delays that sum up to 100µs per clock cycle (50µs per half cycle!) to anything that defines the clock.

    Especially, you cannot simply set and clear the clock in two subsequent operations without a delay in between. This wouldn't work even with high-speed I2C devices.

    Set the data, wait the setup time (see datasheet), set the clock, wait, clear the clock, wait, now you can change the data.

    The DS1307 datasheet contains the necessary setup and hold times for every step of the data transfer.

**Attention** This is a public forum