DS1307 no response

Respected Sir /Madam

I am developing a project for which i have to interface the ds1307 rtc to it. The controller used is 8051 base.

I am not able to read back the registers and get the desired values written to it. Here is my source.Kindly give suggestions and help to change the corrections if any.

void Rtc(void) { I2c_Routine(); // Go to i2c routine }

void I2c_Routine(void) { CFG841 = CFG841 | 0X01; rtc_set_time(0x00); // Initialise the RTC (Clear sec register CH bit) // while(1); Rtc_Write(); while(1) { /* ack_delay(); ack_delay(); ack_delay(); */ rtc_get_time(); Digit_Placement(1,6,0,hour_M); Digit_Placement(1,6,6,hour_L); Display_Line(6,14,&isto[0]);

Digit_Placement(1,6,19,mins_M); Digit_Placement(1,6,25,mins_L); Display_Line(6,31,&isto[0]);

Digit_Placement(1,6,36,seconds_M); Digit_Placement(1,6,42,seconds_L); } }

void Send_Byte(unsigned char data1) { unsigned char i; for(i=0x80; i!=0; i=i>>1) { if((data1 & i) == 0) { SDA = 0; Delay_New(5); } else { SDA = 1; Delay_New(5); } SCL = 1; Delay_New(10); SCL = 0; } get_ack();

}

void Send_Data(unsigned char SLAVEADD) { Send_Byte(SLAVEADD); // Go to Send_Byte routine }

void check_busy(void) { SDA = 1; SCL = 1; if((SCL == 1) && (SDA == 1)) BUSY = 0; else BUSY = 1; }

void Start_Bit(void) { if(BUSY == 0) { // SDA = 1; // SCL = 1; Delay_New(5); SDA = 0; Delay_New(10); // SDATA o/p low for start condition SCL = 0; } }

void Stop_Bit(void) { SDA = 0; Delay_New(5); SCL = 1; Delay_New(10); SDA = 1; }

void get_ack(void) { SDA = 1; Delay_New(5); SCL = 1; Delay_New(10); // while(SDA){} // catch ack from slave(ds 1307) // while(!SDA){} P2_6 = 0; SCL = 0; ack_delay(); P2_6 = 1; Delay_New(20); ack_delay(); // break; }

void give_nack(void) { SDA = 1; // Delay_New(5); SCL = 1; Delay_New(10); SCL = 0; }

void Receive_Byte(void) { unsigned char m = 0; // SCL = 0; SDA = 1; Delay_New(5); readdata = 0x00; for(m=0x80; m!=0; m=m>>1) { SCL = 1; Delay_New(5); if(SDA==1) { readdata |= (m & 0xff); } else if(SDA==0) { readdata |= (m & 0x00); } SCL = 0; } give_nack(); }

void Write_1302(unsigned char addr,unsigned char datawrite) { check_busy(); Start_Bit(); Send_Data(0xD0); // SLAVE ID for DS 1307 Send_Data(addr); // Corresponding register Address of RTC Send_Data(datawrite); // DATA VALUE for the Selected Register Stop_Bit(); }

unsigned char read_1302(unsigned char addr) // incase of correction change this func to return type { check_busy(); Start_Bit(); Send_Data(0xD0); Send_Data(addr); check_busy(); Start_Bit(); Send_Data(0xD1); Receive_Byte(); Stop_Bit(); return(readdata); }

void Rtc_Write(void) { Write_1302(0x07,0x10); //data to control register Write_1302(0x06,0x06); //data to year register Write_1302(0x05,0x01); //data to month register Write_1302(0x04,0x01); //data to date register Write_1302(0x03,0x01); //data to day register Write_1302(0x02,0x00); //data to hour register Write_1302(0x01,0x00); //data to minutes register Write_1302(0x00,0x00); //data to seconds register }

void rtc_set_time(unsigned char sec) { // Write_1302(0x00,(bin2bcd(sec))); Write_1302(0x00,sec); }

void rtc_get_time(void) { unsigned char temp_sec,temp_mins,temp_hour;

temp_sec = read_1302(0x00); temp_mins = read_1302(0x01); hours_d = read_1302(0x02); day_d = read_1302(0x03); date_d = read_1302(0x04); month_d = read_1302(0x05); year_d = read_1302(0x06);

//hours_d = bcd2bin(read_1302(0x02)); //mins_d = bcd2bin(read_1302(0x01)); //temp_sec = bcd2bin(read_1302(0x00)); //seconds_M = ((temp_sec & 0xF0)+ 0x30);

hour_M = (((temp_hour & 0xF0) >> 4) + '0'); hour_M = ((temp_hour & 0x0F) + '0');

mins_M = (((temp_mins & 0xF0) >> 4 ) + '0'); mins_M = ((temp_mins & 0x0F) + '0');

seconds_M = (((temp_sec & 0xF0) >> 4 )+ '0'); seconds_L = ((temp_sec & 0x0F) + '0');

}

unsigned char bin2bcd(unsigned char binval) { unsigned char temp_val; if(binval>0x99) return(0); else { temp_val = binval / 10; temp_val 4) & 0x0F) * 10; temp_val += (bcdval & 0x0F); return (temp_val); }

Thanking all. Regards Navaneethan.

Reply to
nava555
Loading thread data ...

Respected Sir / Madam

I am developing a project to which i have to inerface a DS1307 rtc to it. The controller used is 8051 base system. Here is my source and kindly give me the suggestions & corrections to be done to it. Hence i am very beginner, kindly help me regarding the same.

//source void Rtc(void) { I2c_Routine(); // Go to i2c routine }

void I2c_Routine(void) { CFG841 = CFG841 | 0X01; rtc_set_time(0x00); // Initialise the RTC (Clear sec register CH bit) // while(1); Rtc_Write(); while(1) { /* ack_delay(); ack_delay(); ack_delay(); */ rtc_get_time(); Digit_Placement(1,6,0,hour_M); Digit_Placement(1,6,6,hour_L); Display_Line(6,14,&isto[0]);

Digit_Placement(1,6,19,mins_M); Digit_Placement(1,6,25,mins_L); Display_Line(6,31,&isto[0]);

Digit_Placement(1,6,36,seconds_M); Digit_Placement(1,6,42,seconds_L); } }

void Send_Byte(unsigned char data1) { unsigned char i; for(i=0x80; i!=0; i=i>>1) { if((data1 & i) == 0) { SDA = 0; Delay_New(5); } else { SDA = 1; Delay_New(5); } SCL = 1; Delay_New(10); SCL = 0; } get_ack();

}

void Send_Data(unsigned char SLAVEADD) { Send_Byte(SLAVEADD); // Go to Send_Byte routine }

void check_busy(void) { SDA = 1; SCL = 1; if((SCL == 1) && (SDA == 1)) BUSY = 0; else BUSY = 1; }

void Start_Bit(void) { if(BUSY == 0) { // SDA = 1; // SCL = 1; Delay_New(5); SDA = 0; Delay_New(10); // SDATA o/p low for start condition SCL = 0; } }

void Stop_Bit(void) { SDA = 0; Delay_New(5); SCL = 1; Delay_New(10); SDA = 1; }

void get_ack(void) { SDA = 1; Delay_New(5); SCL = 1; Delay_New(10); // while(SDA){} // catch ack from slave(ds 1307) // while(!SDA){} P2_6 = 0; SCL = 0; ack_delay(); P2_6 = 1; Delay_New(20); ack_delay(); // break; }

void give_nack(void) { SDA = 1; // Delay_New(5); SCL = 1; Delay_New(10); SCL = 0; }

void Receive_Byte(void) { unsigned char m = 0; // SCL = 0; SDA = 1; Delay_New(5); readdata = 0x00; for(m=0x80; m!=0; m=m>>1) { SCL = 1; Delay_New(5); if(SDA==1) { readdata |= (m & 0xff); } else if(SDA==0) { readdata |= (m & 0x00); } SCL = 0; } give_nack(); }

void Write_1302(unsigned char addr,unsigned char datawrite) { check_busy(); Start_Bit(); Send_Data(0xD0); // SLAVE ID for DS 1307 Send_Data(addr); // Corresponding register Address of RTC Send_Data(datawrite); // DATA VALUE for the Selected Register Stop_Bit(); }

unsigned char read_1302(unsigned char addr) // incase of correction change this func to return type { check_busy(); Start_Bit(); Send_Data(0xD0); Send_Data(addr); check_busy(); Start_Bit(); Send_Data(0xD1); Receive_Byte(); Stop_Bit(); return(readdata); }

void Rtc_Write(void) { Write_1302(0x07,0x10); //data to control register Write_1302(0x06,0x06); //data to year register Write_1302(0x05,0x01); //data to month register Write_1302(0x04,0x01); //data to date register Write_1302(0x03,0x01); //data to day register Write_1302(0x02,0x00); //data to hour register Write_1302(0x01,0x00); //data to minutes register Write_1302(0x00,0x00); //data to seconds register }

void rtc_set_time(unsigned char sec) { // Write_1302(0x00,(bin2bcd(sec))); Write_1302(0x00,sec); }

void rtc_get_time(void) { unsigned char temp_sec,temp_mins,temp_hour;

temp_sec = read_1302(0x00); temp_mins = read_1302(0x01); hours_d = read_1302(0x02); day_d = read_1302(0x03); date_d = read_1302(0x04); month_d = read_1302(0x05); year_d = read_1302(0x06);

//hours_d = bcd2bin(read_1302(0x02)); //mins_d = bcd2bin(read_1302(0x01)); //temp_sec = bcd2bin(read_1302(0x00)); //seconds_M = ((temp_sec & 0xF0)+ 0x30);

hour_M = (((temp_hour & 0xF0) >> 4) + '0'); hour_M = ((temp_hour & 0x0F) + '0');

mins_M = (((temp_mins & 0xF0) >> 4 ) + '0'); mins_M = ((temp_mins & 0x0F) + '0');

seconds_M = (((temp_sec & 0xF0) >> 4 )+ '0'); seconds_L = ((temp_sec & 0x0F) + '0');

}

unsigned char bin2bcd(unsigned char binval) { unsigned char temp_val; if(binval>0x99) return(0); else { temp_val = binval / 10; temp_val 4) & 0x0F) * 10; temp_val += (bcdval & 0x0F); return (temp_val); }

Thanking All Regards Navaneethan

Reply to
nava555

Repeating your post every 30 minutes will not help, especially in different threads. It will only annoy. Neither will posting non-compilable code. Cut your indentation level to 3 or 4 spaces per level, use spaces, not tabs, eschew // comments (they don't travel well over usenet, and are not even legal in C90 standards systems). Comment each routine as to what it does in broad terms, and most important, ensure that the source is compilable.

Usenet is not google. Google is a very poor interface to usenet, which can, with care, be used intelligently. Please read the references in my sig. below BEFORE posting again.

--
"If you want to post a followup via groups.google.com, don't use
 the broken "Reply" link at the bottom of the article.  Click on 
 "show options" at the top of the article, then click on the 
 "Reply" at the bottom of the article headers." - Keith Thompson
More details at: 
Also see
Reply to
CBFalconer

I don't think anyone is going to bash through your code. I2C is pretty straightforward. The best thing is to get the datasheet and a scope. Attach the scope to the lines to the chip, and compare what you see with what the datasheet says should be there. Modify program until they are the same.

Paul Burke

Reply to
Paul Burke

You know, this is depressing because you *may* just say something in future which will be germane to comp.arch.embedded and of interest to me; but you're going in my killfile.

Of your posts which I have seen, approximately 75% are raging against Google and/or top-posting and/or message layout but contain no useful information about the OP's question/problem.

Get over it.

Reply to
Jim D.

Disclaimer: I don't know too much about 8051, but I have implemented I2C on more than one occasion.

Your code does 'SDA=1' and 'SDA=0', as well as 'if ( SDA == 1)'

How is 'SDA' defined ? The SDA/SCL pins are supposed to be open-drain, with pull-up resistors. In software, this can be typically be implemented by writing SDA output as "0", and then toggle the data direction between input/output. If your "SDA" bit refers to the data direction, then it makes no sense to read that back. You'll need to read back some other register bit to get the current SDA status.

Reply to
Artenz

How then will the newbs be educated concerning the conventions of this long established news group?

Chuck is only trying to educate and improve the signal-to-noise ratio of this forum.

--
Michael N. Moran           (h) 770 516 7918
5009 Old Field Ct.         (c) 678 521 5460
Kennesaw, GA, USA 30144    http://mnmoran.org

"So often times it happens, that we live our lives in chains
  and we never even know we have the key."
The Eagles, "Already Gone"

The Beatles were wrong: 1 & 1 & 1 is 1
Reply to
Michael N. Moran

Arentz,

On the 8051, there is no data direction register. The I/O pins are open drain with pull-up. This means that SDA = 0 will pull the line low and SDA =

1 will release the line. And when SDA is set to '1', a read back of SDA will reflect the state of the line, thus 0 if pulled low by an external device.

Meindert

Reply to
Meindert Sprang

A laudable cause with which I agree.

However, if he also wishes to educate then it wouldn't harm to help the OP with their initial query at the same time as "educating" them how to use Usenet.

Just my 2c worth, I'm not looking to spawn a massive OT thread ;-)

Rgds, Jim

Reply to
Jim D.

He *is* helping the OP. I have used the DS1307 and have C code for it. But I for one was in fact put off replying due to the posting style of the OP. It just seemed like it would be a lot of work communicating effectively with him.

Yes, well I thought your comments were uncalled for. Chuck is a long standing regular and appreciated contributor to this and other groups. *Someone* has to educate the newbies otherwise we may as well all pack up and go to yahoo...

--

John Devereux
Reply to
John Devereux

Thanks for the encouragement. The real problem is google, and their inane interface. In the past I have tried to point out to them that this interface is making them a laughing stock in the technically educated world, and quite possibly depressing their stock price. They are not too likely to take the last too seriously considering their recent history. But if they would fix it we could go back to harassing top-posters and non-clippers. :-)

To Jim D: That's what killfiles are for - to remove annoyances. Many autokill anything originating from google, which I have not done. I even kill the periodic publication of the cfaq, not because it is evil, but because I have seen it, have a copy, and just don't want to download and delete it again. Similarly publicizing PLONKs and their reasons may eventually improve the breed. Failure to publicize is like yelling at the puppy the day after the offense.

As a matter of fact I believe that if people failed to respond to context free google replies (whew - silly phrase) other than instructions such as mine, we would educate the googlebugs much more rapidly. There are some googolians who are very well behaved.

--
"The power of the Executive to cast a man into prison without
 formulating any charge known to the law, and particularly to
 deny him the judgement of his peers, is in the highest degree
 odious and is the foundation of all totalitarian government
 whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Reply to
CBFalconer

IIRC, that is what a FAQ is supposed to do.

Repetitive signals with no new information content can be just as bothersome as noise. (A problem that is vexing me in an engineering project in progress.)

Mark Borgerson

Reply to
Mark Borgerson

The OP probably doesn't know what a FAQ is! He first posted about his problem in comp.lang.forth!

The information was evidently new to the OP.

--

John Devereux
Reply to
John Devereux

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.