Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] DS1307 Reading Problem with PIC16F877A (URGENT PLS)

Status
Not open for further replies.

xpress_embedo

Advanced Member level 4
Joined
Jul 5, 2011
Messages
1,154
Helped
161
Reputation
396
Reaction score
189
Trophy points
1,353
Location
India
Activity points
10,591
I had interface the RTC DS1307 with my PIC Micro-Controller... and using the internal I2C Module of PIC

I had successfully write some bytes but not able to read the byte properly..

I had set the time as 06-05-00 (Hours-Min-Sec) Format.

I tried reading the data and displaying on the LCD, but i get time as
TIME:05:00:06

Means Minutes then Seconds and then Hours

One can thought i had not written the LCD Routines properly, but this is not the case, the problem is in reading..

sec = rtc1307_read(0x00);
//this must read seconds..
but it reads second during its first run and minutes in its second run
and due to this reading problem, i am suffering when i want to display time on LCD

Here is my Code
Code:
#include <htc.h>
#include<string.h>

#define _XTAL_FREQ 20000000

#define LCD_DATA PORTD
#define RS PORTBbits.RB0
#define RW PORTBbits.RB2
#define EN PORTBbits.RB1

//Function Prototype
void lcd_init();
void lcdcmd(unsigned char value);
void lcddata(unsigned char value);
void lcdstr(unsigned char msg[]);
void i2c_init();
void i2c_start(void);
void i2c_Ack();
void i2c_Nack();
void i2c_restart(void);
void i2c_stop(void);
void i2c_wait(void);
void i2c_send(unsigned char dat);
unsigned char rtc1307_read(unsigned char address);
unsigned char i2c_read(void);
unsigned char BCD2UpperCh(unsigned char bcd);
unsigned char BCD2LowerCh(unsigned char bcd);

unsigned char sec,min,hour;
unsigned char flag = 0;

void main()
{
	TRISB = 0x00;
	TRISC = 0xFF;
	TRISD = 0x00;
	lcd_init();
	lcdcmd(0x80);
	__delay_ms(10);
	lcdstr("RTC Test");
	i2c_init();	//To Generate the Clock of 100Khz
	i2c_start();
	i2c_send(0xD0);
	i2c_send(0x00);
	i2c_send(0x80);	//CH = 1 Stop oscillator
	i2c_send(0x05);
	i2c_send(0x06);
	i2c_send(0x01);	//Sunday
	i2c_send(0x01);	//1Date
	i2c_send(0x01);	//1 Jan
	i2c_send(0x12);	//2012
	i2c_stop();
	//Have to start the Clock again
	i2c_start();
	i2c_send(0xD0);
	i2c_send(0x00);
	i2c_send(0x00);	//start Clock
	i2c_stop();
	
	while(1)
	{
		i2c_start();
		i2c_stop();
		lcdcmd(0x01);
		sec = rtc1307_read(0x00);
		/*min = rtc1307_read(0x01);
		__delay_ms(1);
		hour = rtc1307_read(0x02);
		__delay_ms(1);
		lcdstr("Time:");
		lcddata(BCD2UpperCh(hour));
		lcddata(BCD2LowerCh(hour));
		lcddata(':');
		lcddata(BCD2UpperCh(min));
		lcddata(BCD2LowerCh(min));
		lcddata(':');*/
		lcddata(BCD2UpperCh(sec));
		lcddata(BCD2LowerCh(sec));
		__delay_ms(100);
	}	
}

//Fnction Definition
void lcd_init()
{
	lcdcmd(0x38);
	__delay_ms(1);
	lcdcmd(0x0E);	
	__delay_ms(1);
	lcdcmd(0x0C);
	__delay_ms(1);
}
void lcdcmd(unsigned char value)
{
	LCD_DATA = value;
	RS = 0;
	RW = 0;
	EN = 1;
	__delay_ms(1);
	EN = 0;
}
void lcddata(unsigned char value)
{
	LCD_DATA = value;
	RS = 1;
	RW = 0;
	EN = 1;
	__delay_ms(1);
	EN = 0;
}
void lcdstr(unsigned char msg[])
{
	unsigned int i,len;	
	len = strlen(msg);
	for(i=0;i<len;i++)
	{	
		lcddata(msg[i]);
		__delay_ms(1);
	}
}
void i2c_init()
{
	TRISC3 = 1;
	TRISC4 = 1;
	SSPSTAT |= 0x80; //Slew Rate Disabled
	SSPADD = 49;
	
	SSPCON=0b00101000;			//Master mode
	SSPADD = 49;
	/*SSPEN = 1
	Enables the Serial Port and configures the SDA and SCL
	Pins as the Serial Pins
	SSPM3:SSPM0 --> 1000
	I2C Master Mode
	Clock = Fosc/4*(SSPADD+1)
	*/
}

void i2c_start(void)
{
	SEN = 1;
	//SSPCON2 bit 0
	while (SEN == 1)
		continue;
	//SEN =1 initiate the Start Condition on SDA and SCL Pins
	//Automatically Cleared by Hardwre
	// 0 for Idle State
}

void i2c_restart(void)
{
	RSEN = 1;
	//SSPCON2 bit 1
	while (RSEN == 1)
		continue;
	//RSEN = 1 initiate the Restart Condition
	//Automatically Cleared by Hardware
}

void i2c_stop(void)
{
	PEN=1;
	while(PEN==1)
		continue;
}

void i2c_wait(void)
{
	while( R_W == 1)
		continue;
	if(ACKSTAT == 1)
	{
		i2c_stop();
	}
	//If ACKSTAT bit is 0 Acknowledgment Received Successfully
	//Otherwise Not
}

void i2c_send(unsigned char dat)
{
	SSPBUF = dat;    /* Move data to SSPBUF */
    while(BF);       /* wait till complete data is sent from buffer */
    i2c_wait();       /* wait for any pending transfer */
}

unsigned char i2c_read(void)
{
	unsigned char temp;
    RCEN = 1;        /* Enable data reception */
    while(!BF);      /* wait for buffer full */
    temp = SSPBUF;   /* Read serial buffer and store in temp register */
    i2c_wait();       /* wait to check any pending transfer */
    return temp;     /* Return the read data from bus */
}

unsigned char BCD2UpperCh(unsigned char bcd)
{
	unsigned char temp;
 	temp = bcd >> 4;
 	temp = temp | 0x30;
 	return(temp);	
}
unsigned char BCD2LowerCh(unsigned char bcd)
{
	unsigned char temp;
 	temp = bcd & 0x0F; //Making the Upper 4-bits
 	temp = temp | 0x30;
 	return(temp);
}

unsigned char rtc1307_read(unsigned char address)
{
	unsigned char temp1;
	i2c_start();
	i2c_send(0xD0);
	i2c_send(address);
	i2c_restart();
	i2c_send(0xD1);
	temp1 = i2c_read();
	i2c_stop();	
	return temp1;
}
void i2c_Ack()
{
	ACKDT = 0;	//Acknowledge Data Bit, 0 = Ack
	ACKEN = 1;	//Acknowledge Enable Bit
	while(ACKEN);
	//Wait for ack bit to send on bus
}
void i2c_Nack()
{
	ACKDT = 1;
	ACKEN = 1;	//Acknowledge Enable Bit
	while(ACKEN);
}


I am also attaching my schematic

rtc.png

Pls help me
 

i had a look at the DS1307 datasheet .. and found that the seconds hours minutes etc are saved in registers and have fixed address rather than format
are you sure you have read through the datasheet and are implementing things correctly

---------- Post added at 13:30 ---------- Previous post was at 13:18 ----------

ok - i read into further detail .. didnt understand the necessity of i2c_restart()
i read the read/write sequence of DS1307 .. have a doubt about the D0 and D1 you use for reading

 
There is the need of restart during the reading mode...

Actually my reading functions are not okay...


FROM DATASHEET
The
slave address byte contains the 7-bit DS1307 address, which is 1101000, followed by the direction bit
(R/W), which is 1 for a read. After receiving and decoding the slave address the DS1307 outputs an
acknowledge on SDA. The DS1307 then begins to transmit data starting with the register address
pointed to by the register pointer. If the register pointer is not written to before the initiation of a read
mode the first address that is read is the last one stored in the register pointer. The register pointer
automatically increments after each byte are read. The DS1307 must receive a Not Acknowledge to
end a read.

And I am getting 'A' while required is 'N' it gets solved..

Changed some part of reading function and it works for me..
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top