|
|
View previous topic :: View next topic |
Author |
Message |
nisha
Joined: 09 Nov 2011 Posts: 6 Location: mumbai
|
ds1307 time is automatically decreasing |
Posted: Mon Oct 22, 2012 3:47 am |
|
|
I'm using ds1307 interfaced with pic16f877a. My code is working but the problem is, if I'm continuously keeping it on, the time goes on reducing. Say after 10 to 15 min it will decrease by 1 sec, which will create a problem after some hour or some days.
Plz help me. _________________ Nisha Yetiwar |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Mon Oct 22, 2012 3:55 am |
|
|
Are you getting the time once from the DS1307 and then running an internal based clock on the PIC or reading the time from the 1307 every time?
If the former, then you have to remember that if you're not using a crystal for the PIC that evenly divides out by the timer you're using, you can end up with slippage. A smaller number than an even divider and your clock runs too fast. A larger number than the divider and your clock runs too slow.
In the case of the latter, it sounds like the clock source for the 1307 is running fast.
If I remember right, the 1307 has pins to allow measuring the 32.768KHz clock through a buffer.
You should do that. If you have a frequency counter, that's most likely a better option than a scope.
Additionally, how is this DS1307 wired? on a breadboard?
Did you read the datasheet for the DS1307 and note all the commentary about critical layout for the crystal connection? (if you're using a crystal) _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Mon Oct 22, 2012 8:16 pm |
|
|
Adding to bkamen's comments,
The DS1307 requires a crystal that operates with 12pf loading. Two common mistakes when using this chip is to use the wrong crystal and the other is to add two external 12pF capacitors when this is already built into the chip. In both scenarios the frequency will be wrong. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
nisha
Joined: 09 Nov 2011 Posts: 6 Location: mumbai
|
|
Posted: Thu Oct 25, 2012 1:14 am |
|
|
i m using 32.768khz crystal, for ds1307. yes but i have not connected 12pf cap to my crystal..i searched for ckt diagram on net, there 12pf was connected. is it necessary..
And i m not using breadboard, components and wires are properly soldered
For pic16f877a, i m using 4Mhz external crystal.should i go for higher freq. _________________ Nisha Yetiwar |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Thu Oct 25, 2012 1:49 am |
|
|
nisha wrote: | i m using 32.768khz crystal, for ds1307. yes but i have not connected 12pf cap to my crystal..i searched for ckt diagram on net, there 12pf was connected. is it necessary..
And i m not using breadboard, components and wires are properly soldered
For pic16f877a, i m using 4Mhz external crystal.should i go for higher freq. |
The capacitors are not necessary. Check the Dallas (Maxim-IC) data sheet.
Are you using the correct crystal?
Are you reading the chip correctly - not inadvertently starting and stopping the oscillator? _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19536
|
|
Posted: Thu Oct 25, 2012 1:52 am |
|
|
OK.
First thing is forget about the 'net'. Look instead at the actual data sheet for the clock chip. Paragraph about the crystal:
"The internal oscillator circuitry is designed for operation with a crystal having a specified load capacitance (CL) of 12.5 pF".
So, what is the specified load capacitance of _your_ crystal. If it is one that requires 6pF capacitance (quite common for 32KHz crystals), then the Cl of the IC will be too high, and the circuit _will_ run slow.
Now, the reason I say 'forget about the net', is that while a huge amount of good data does get published, a lot of incorrect things also do. You see people using 12pF capacitors on crystals that require a 12pF load - wrong - the crystal sees the two capacitors in series, and paralleled to the pin/track capacitance, so even where a capacitor is needed, this gives completely the wrong load.
The crystal pins of the DS1307, are designed to already give a 12.5pF load, and provided your crystal wants this load, external capacitors are not wanted.
However careful layout is. "Carefully soldered", but to what?. The traces to the crystal need to be _short_. The chip is designed to have just a fraction of a pF of stray capacitance on the tracks. More than a few mm of track, and again the load will be more than required. You also need to avoid running (for example) a ground plane actually round the crystal legs. This again increases capacitance, and will slow the clock. What you want is a 'guard ring' round outside the pins, that is itself tied to ground, leaving an oval of bare board on the top of the board round the actual legs, and then run a ground plane under the board (bottom layer).
The frequency of the PIC doesn't really matter here.
However you do need to be aware of what overall accuracy you can expect. Watch crystals are remarkably forgiving, but are at there most accurate in reasonably temperature stable environment. Gently held at a nice body temperature on your wrist, they give better accuracies than they will with wider temperature changes. The curve as temperature changes, is parabolic, so reasonably flat for the temperatures between 20C, and perhaps 28C, but go to temperatures like 10C, and the accuracy will descend. The initial tolerance on a typical watch crystal, will be +/-20ppm, which gives an error of 1.73 seconds per day. Add temperature errors, and this can easily be three or four seconds per day, even if everything is built as it should be. Too get better than this, you have to go to actually trimming the crystal (which the DS1307 is not designed to allow), and temperature regulating. So your error is at least an order of magnitude 'worse' than it should be. The fact that it is slow, suggests there is too much capacitance (so adding capacitors is _not_ the way to go). Either the crystal you have is designed for a lower load, or your layout is adding a lot of stray capacitance.
Best Wishes |
|
|
nisha
Joined: 09 Nov 2011 Posts: 6 Location: mumbai
|
|
Posted: Thu Oct 25, 2012 4:50 am |
|
|
And this is my driver file
Code: |
#define RTC_SDA PIN_C4
#define RTC_SCL PIN_C3
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);
void ds1307_init(void)
{
BYTE seconds = 0;
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_start();
i2c_write(0xD1); // RD from RTC
seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
i2c_stop();
seconds &= 0x7F;
delay_us(3);
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_write(bin2bcd(seconds)); // Start oscillator with current "seconds value
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x07); // Control Register
i2c_write(0x10); // Enable 10 squarewave output pin // disable 10000000=80
i2c_stop();
}
void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
sec &= 0x7F;
hr &= 0x3F; //3f
i2c_start();
i2c_write(0xD0); // I2C write address
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_write(bin2bcd(sec)); // REG 0
i2c_write(bin2bcd(min)); // REG 1
i2c_write(bin2bcd(hr)); // REG 2
i2c_write(bin2bcd(dow)); // REG 3
i2c_write(bin2bcd(day)); // REG 4
i2c_write(bin2bcd(mth)); // REG 5
i2c_write(bin2bcd(year)); // REG 6
i2c_write(0x10); // REG 7 - Disable squarewave output pin //disable=80
i2c_stop();
}
void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03); // Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
dow = bcd2bin(i2c_read() & 0x7f); // REG 3
day = bcd2bin(i2c_read() & 0x3f); // REG 4
mth = bcd2bin(i2c_read() & 0x1f); // REG 5
year = bcd2bin(i2c_read(0)); // REG 6
i2c_stop();
}
void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
sec = bcd2bin(i2c_read(1) & 0x7f);
min = bcd2bin(i2c_read(1) & 0x7f);
hr = bcd2bin(i2c_read(1) & 0x7f); //3f
//year = bcd2bin(i2c_read(0));
i2c_stop();
}
BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;
temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;
// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));
} |
_________________ Nisha Yetiwar
Last edited by nisha on Thu Oct 25, 2012 4:51 am; edited 1 time in total |
|
|
nisha
Joined: 09 Nov 2011 Posts: 6 Location: mumbai
|
|
Posted: Thu Oct 25, 2012 4:50 am |
|
|
This is my Main program, please tell me where is the mistake. I changed my crystal from 4 to 20 Mhz of PIC.
Code: |
#include <16f877A.h>
#FUSES NOWDT, HS, NOPUT, PROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#include <ds_driver.c>
#byte porta= 0x05
#byte portb= 0x06
#byte portc= 0X07
#byte portd= 0X08
#byte porte= 0X09
#byte trisa= 0x85
#byte trisb= 0x86
#byte trisc= 0X87
#byte trisd= 0X88
#byte trise= 0X89
void clear(void);
void bin_2_bcd(int16, int16, int16, int16, int16);
int32 hour, minute, second, dat, month, year, day, time, total_disp;
int8 D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,i,prog;
int8 seven_table[27]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x79,0x50,0x5c};
// E r o
char dt, mth, yr, dow, hr, min, sec;
#int_EXT
EXT_isr()
{
ds1307_get_date(dt,mth,yr,dow);
ds1307_get_time(hr,min,sec);
}
#int_TIMER2
TIMER2_isr()
{
switch(i)
{
case 0 : output_low(PIN_E2); output_d(seven_table[D1]); output_high(PIN_B4); i=1; break;
case 1 : output_low(PIN_B4); output_d(seven_table[D2]); output_high(PIN_B5); i=2; break;
case 2 : output_low(PIN_B5); output_d(seven_table[D3]); output_high(PIN_C0); i=3; break;
case 3 : output_low(PIN_C0); output_d(seven_table[D4]); output_high(PIN_C1); i=4; break;
case 4 : output_low(PIN_C1); output_d(seven_table[D5]); output_high(PIN_C5); i=5; break;
case 5 : output_low(PIN_C5); output_d(seven_table[D6]); output_high(PIN_C6); i=6; break;
case 6 : output_low(PIN_C6); output_d(seven_table[D7]); output_high(PIN_C7); i=7; break;
case 7 : output_low(PIN_C7); output_d(seven_table[D8]); output_high(PIN_E0); i=8; break;
case 8 : output_low(PIN_E0); output_d(seven_table[D9]); output_high(PIN_E1); i=9; break;
case 9 : output_low(PIN_E1); output_d(seven_table[D10]); output_high(PIN_E2); i=0; break;
}
}
void main(void)
{
int8 temp=0;
delay_ms(100);
output_low(PIN_B4); output_low(PIN_B5); output_low(PIN_C0); output_low(PIN_C1); output_low(PIN_C5);
output_low(PIN_C6); output_low(PIN_C7); output_low(PIN_E0); output_low(PIN_E1); output_low(PIN_E2);
i=0; time=0;
clear();
ds1307_init();
setup_timer_2(T2_DIV_BY_4,250,1); enable_interrupts(INT_TIMER2);
enable_interrupts(INT_EXT); enable_interrupts(GLOBAL);
ds1307_set_date_time(25,10,12,4,4,30,10); //date,mth,yr,dow,hr,min,sec
while(1)
{
dat=dt;month=mth;year=yr;
hour=hr; minute=min; second=sec;
bin_2_bcd(hour, minute, second, dat, month); //right nw i have only 10 display,that's why i m display only this much.
}
}
void clear(void)
{
D1=0; D2=0; D3=0; D4=0; D5=0; D6=0; D7=0; D8=0; D9=0; D10=0; dt=0; mth=0; yr=0;dow=0; hr=0; min=0; sec=0; day=0; time=0; dat=0; month=0; year=0; hour=0; minute=0; second=0;}
void bin_2_bcd(int16 hour, int16 minute, int16 second, int16 dat, int16 month)
{
D10=month%10;
month/=10;
D9=month%10;
D8=dat%10;
dat/=10;
D7=dat%10;
D6=second%10;
second/=10;
D5=second%10;
D4=minute%10;
minute/=10;
D3=minute%10;
D2=hour%10;
hour/=10;
D1=hour%10;
} |
_________________ Nisha Yetiwar
Last edited by nisha on Thu Oct 25, 2012 5:05 am; edited 3 times in total |
|
|
nisha
Joined: 09 Nov 2011 Posts: 6 Location: mumbai
|
|
Posted: Thu Oct 25, 2012 4:56 am |
|
|
i am using square wave op of my ds whose freq is 1 hz, which is connected to the RB0 pin of my pic controller,
means i am using external interrupt, which will read data after every 1 sec.. _________________ Nisha Yetiwar |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Thu Oct 25, 2012 9:25 am |
|
|
nisha wrote: | i am using square wave op of my ds whose freq is 1 hz, which is connected to the RB0 pin of my pic controller,
means i am using external interrupt, which will read data after every 1 sec.. |
1Hz or 1.000Hz or 1.001Hz?
Decimal points matter here.
If you say (in your original post) that your clock is short 1sec after 10-15min. (we'll use 10min as a starting point) then...
599sec / 600 (which is 10min) = 0.99833
So your clock is 0.99833 Hz, not 1.0000Hz
Again - the DS1307 has a buffered CLK output to measure the crystal. Yes. It's also the OUT pin (#7) so you'll need to re-program it for a moment to measure FREQ instead of seconds.
Again, it sounds like your crystal is running fast.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|