Forum: Mikrocontroller und Digitale Elektronik Real-Time Clock (ds1307)


von sven s. (Gast)


Lesenswert?

hallo zusammen,

ich hab mir einen ds1307 besorgt und an einen mega16 angeschlossen.(wer 
den code haben will einfach melden)
soweit geht auch alles kann die zeit reinschreiben und die uhr läuft 
auch.
allerdings wenn ich die 5 volt versorgung weg nehme bleibt das ding 
einfach stehen, ich weis jetzt nicht ob ich einfach nur zu doof bin aber 
ich dachte das ding läuft mit der 3v lithium batterie weiter.

msg sven


von Mike (Gast)


Lesenswert?

Auch wenn's vielleicht trivial klingt:
Batterie richtigrum angeschlossen? Batteriespannung zu niedrig? Es sind 
mindestens 2.0V nötig, sonst schaltet sich die Uhr ab. Es sollte keine 
Diode zwischen Pluspol der Batterie und VBat- Anschluss sein.

Bleibt denn das RAM erhalten?

Gruss
Mike

von Matthias (Gast)


Lesenswert?

Poste doch mal bitte deine Schaltung

von sven s. (Gast)


Angehängte Dateien:

Lesenswert?

die batterie hat noch 2,8volt und eine diode ist nicht drin wie man auf 
dem schaltplan sehen kann.
die daten bleiben auch im ram.

mfg sven

von sven s. (Gast)


Angehängte Dateien:

Lesenswert?

hier noch das layout

von sven s. (Gast)


Lesenswert?

weis den keiner an was das liegen könnte.

bitte helft mir ich komm nicht mehr weiter, das ist doch zum 
verzweifeln.

von Matthias (Gast)


Lesenswert?

Nun, was mich an dem Teil interessiert:

Ich kenne die RTC74423 von EPSON. Die hat einen Chip Select Anschluß. 
Ist dieser LOW, so ist das IC auf standby. Da wird garantiert, die 
Funktion bis 2V Betriebsspannung aufrechtzuhalten. Die geschieht über 
Godcap-Kond. (welche mit einer Diode von 5V getrennt ist). Erst werden 
die 5V zugeschalten und dann wird mittels des Chip-select-Signals das IC 
wieder freigegeben (für Bedienung).

Sowas hat aber der DS1307 nicht... Was ist wenn jetzt die 
Betriebsspannung sinkt, mit den SCL und SDA Leitungen.. Die sinken auch, 
weil der Pullup nicht mehr geht.. Wird das jetzt nicht irgendwie als 
Start-I2C erkannt....??
Wie ist das bei dem DS1307 gedacht??
Nicht das das Problem aus der Richtung kommt....

von sven s. (Gast)


Lesenswert?

auch wenn er es als start erkennt würde dann nicht die uhr anhalten.
hab auch mal die scl und sda leitungen mit pull up auf plus der batterie 
gelegt hat auch nichts gebracht:

ich könnte noch einen hardware defekt vermuten aber das wär sehr komisch 
da ja alle anderen funktionen gehen.

evtl hab ich ja was nicht beachtet hab jetzt zum ersten mal was mit i2c 
gemacht. ich nehm sonst lieber spi oder uart.

ich weis nicht mehr weite ich kann nur auf eure hilfe hoffen.

von Henrik J. (henrikj)


Lesenswert?

Ich weiß von ner anderen RTC, dass ma den Oscillator abschalten kann. 
Anscheinend geht das mit der DS1307 auch. Auf Seite 2 des Datenblatts 
werden verschiedene Ströme beschrieben. Ich würdemal bisschen mit den 
Konfigurationsbits spielen.

Ich habe die DS1307 auvch verbaut jedoch in Ermangelung von Zeit noch 
kein Stückchen Code geschrieben. Kannst du mir den zukommen lassen?

henrik.jahnke   (at ) web(.)de

von sven s. (Gast)


Angehängte Dateien:

Lesenswert?

hier mal der code in einer beta version ohne viel schnick schnack.

@Henrik Jahnke
ich hoffe du kannst mir sagen ob der fehler bei dier auch auftritt um 
den fehler weiter einzugrenzen.

von Henrik J. (henrikj)


Lesenswert?

Ui! Dann soll ich deinen Code mal reinflashen? Hmm... Das wird 
vielleicht morgen was. Eigentlich ist Zeit gerade knapp wegen Diplom 
schreiben. Ich hab auch nen Mega16 mit der DS1307. Würde es da nicht 
auch gehen, dass du mir ein HexFile schickst? Das müsste eigentlich 
funzen, oder?! Hab nen 16MHz Quarz dran.

EDIT: Hab gerade mal mein WinAVR angeworfen. Ich brauch noch deine twi.h

Ultraedit: Bei 2,8V ist das Ding schön gut leer gelutscht. Meine (steht 
schon ca 0,5 Jahre eingebaut und aber ohne Betrieb) hat noch 3,23V.

von Stephan (Gast)


Lesenswert?

Warum legst Du SQW/Out Pin7 mit einem Jumper gegen Masse?

Schreibst Du nach dem Neustart noch irgendetwas zur 1307, oder fragst Du 
direkt die Zeit ab ?

von sven s. (Gast)


Angehängte Dateien:

Lesenswert?

@Stephan

in dieser beta ja da setz ich die zeit in der fertigen version natürlich 
net. @ quellcode

>Warum legst Du SQW/Out Pin7 mit einem Jumper gegen Masse?

das soll kein jumper sondern eine stiftleiste sein zum anschluss an ein 
oszi oder was auch immer man damit anstellen will. war eh nur zum testen 
gedacht da ich so ein signal nicht wirklich verwenden kann.

@Henrik Jahnke

hier mal die .hex für den m16 mit 9600 baut auf 16mhz
mit "s" wird die zeit (nicht variabel) eingestellt
mit "t" wird der oszilator angehalten
mit "0" wird register 0 ausgelesen
und mit "7" wird register 7 ausgelesen
die zeit kommt immer bei jedem zeichen.

ich benutz jetz eine neue batterie mit 3,2 volt

von Henrik J. (henrikj)


Lesenswert?

Jau! Die Anzeige mit Zeit einstellen usw. ist zwar bisschen kryptisch. 
Aber es hat gereicht, dass ich dir sagen kann:
Bei mir funzt es! Ich hab die Zeit (irgendwie) gestellt. Dann durch 
Tastendruck die aktuelle Zeit abgerufen. 10sec später nochmal 
Tastendruck -> 10 sec vergangen. Also zählt die Uhr erstmal.

Dann hab ich mir die Zeit gemerkt und nochmal von der RTC anzeigen 
lassen. Strom abgezogen und 30sec später wieder Strom angesteckt. Neu 
verbunden per RS232 und siehe da -> Uhrzeit war 30sec weiter.

Liegt also vielleicht wirklich an der Batterie. Bei mir funzt dein Code. 
AM besten ne Nacht drüber schlafen. Vielleicht kommt dann nochmal ne 
Erleuchtung.

An der twi.h und twi.c bin ich trotzdem noch interessiert. :)

von sven s. (Gast)


Angehängte Dateien:

Lesenswert?

so ein mist dann wird wohl echt mein ic ne macke haben.

na egal wenigstens ist der code io. diese fehler in der ausgabe sind 
noch ein paar debug reste die ich noch nicht weg gemacht haben.

anbei noch der header für dich.

danke für deine schnelle hilf, hat mich auf jeden fall weiter gebarcht.

von Matthias (Gast)


Lesenswert?

könnt ihr mir mal nen schaltplan posten? mich interessiert die 
spannungsversorgung der rtc über batterie und die spann.vers. des µC

Danke

von Henrik J. (henrikj)


Angehängte Dateien:

Lesenswert?

Das ist völlig unspektakulär... Ist im Anhang. Wobei ich die beiden C's 
für den Oszillator nicht bestückt habe. Hab mir die Schwingung aber auch 
noch nicht angeschaut.

Bzgl Code. Der hat ein Copyright? Das nervt ja...

von G.a.s.t (Gast)


Lesenswert?

@sven s.
hast du dein Problem breits gelöst?
hab genau das selbe problem die uhr steht einfach aber ich kann die 
einzelnen register lesen und beschreiben.
Vbat ist auf Masse gelegt, da ich zum testen keine batterie verwende.
habe auch bereits deinen code versucht aber es klappt einfach nicht...

von puffel (Gast)


Lesenswert?

G.a.s.t schrieb:
> @sven s.
> hast du dein Problem breits gelöst?

Bestimmt, ist ja schon drei Jahre alt. ;)

> hab genau das selbe problem die uhr steht einfach aber ich kann die
> einzelnen register lesen und beschreiben.

Da läuft der Oszillator nicht:

1. Entsprechendes Bit (CH) gelöscht (Adresse 0x00, Bit 7)?
2. Uhrenquarz angeschlossen?

Testhalber kannst Du mal eine 0x10 an die Adresse 0x07 schreiben, danach 
müsste der SQW/OUT-Ausgang im Sekundentakt zwischen High und Low 
umschalten, wenn der Oszillator läuft.

> Vbat ist auf Masse gelegt, da ich zum testen keine batterie verwende.
> habe auch bereits deinen code versucht aber es klappt einfach nicht...

Er hatte das Problem, dass seine Uhr nach wegnehmen der Betriebsspannung 
stehengeblieben ist. Ohne Batterie wird bei Dir natürlich alles 
gelöscht.

von G.a.s.t (Gast)


Lesenswert?

ok da problem ist nicht ganz das selbe...
einen neuen beitrag wollte ich nicht extra anfangen.

ja das CH hab ich gelöscht
1
temp = ds1307_read(0);
2
3
temp &= ~(1 << 7);
4
5
ds1307_write(0x00,temp);

quarz ist natürlich an Pin 1,2 direkt neben dem sockel angeschlossen.

am sqw messe ich nichts brauch ich da nicht einen pullup dazu?

von sven s. (Gast)


Lesenswert?

ja klar das läuft jetzt auch schon ewig ohne probleme:-)
ich hatte da am quarz winzige krichströme die im 5volt betrieb nix 
gemacht haben, aber dann im bat betrieb brach der oszilator zusammen.

guck bitte noch mal im datenblatt ich erinner mich wage das ohne bat es 
zu problemen im betrieb kommen kann. oder mach einfach mal ne 3 volt bat 
drann.

der code von oben is ein testcode und ist zum testen auch ok. wenn du 
willst kann ich dir morgen mal den code aus dem fertigen projekt 
rausschneiden.

gruß sven

von puffel (Gast)


Lesenswert?

G.a.s.t schrieb:
> am sqw messe ich nichts brauch ich da nicht einen pullup dazu?

Ja, da muss ein pull-up ran.

von G.a.s.t (Gast)


Lesenswert?

endlich zählt er.
das problem lag daran dass ich vbat auf gnd gelegt habe was ich in einem 
anderen thread gelesen habe.
jetzt bin ich draufgekommen das davon nichts im datenblatt steht.

von Besserwisser (Gast)


Lesenswert?

Sobald die Batterie weg ist, steht der Quarz und die Uhr läuft nicht 
mehr. Wenn Du Vbat auf Masse legst, läuft die Uhr nie.
Wenn Du Vbat angschlossen hast, einmal die Uhrzeit stellen und dann 
läuft sie. Sie hat eine interne Spannungsumschaltung. Wenn Vcc kleiner 
Vbat wird, wird der I2C-Bus gesperrt und keine Kommandos angenommen.

von puffel (Gast)


Lesenswert?

Besserwisser schrieb:
> Sobald die Batterie weg ist, steht der Quarz und die Uhr läuft nicht
> mehr. Wenn Du Vbat auf Masse legst, läuft die Uhr nie.

Falsch. Im Datenblatt steht:

"Backup Supply Input for Any Standard 3V Lithium Cell or Other Energy 
Source. Battery voltage must be held between the minimum and maximum 
limits for proper operation. Diodes in series between the battery and 
the VBAT pin may prevent proper operation. If a backup supply is not 
required, VBAT must be grounded."

Das ist auch logisch. Wenn Vbat kein definiertes Potential deutlich 
unterhalb von Vcc hat, kann es Probleme beim Umschalten zwischen Vcc und 
Vbat geben.

Mit Vbat auf GND muss der DS1307 wunderbar laufen (solange Vcc aktiv 
ist), ansonsten stimmt irgendwas an der Verschaltung nicht.

von puffel (Gast)


Lesenswert?

puffel schrieb:
> Das ist auch logisch. Wenn Vbat kein definiertes Potential deutlich
> unterhalb von Vcc hat, kann es Probleme beim Umschalten zwischen Vcc und
> Vbat geben.

Genauer kann es da Probleme geben, die Versorgung stabil an Vcc zu 
halten, weil bei einem offenen Vbat der "Mindestabstand" zwischen Vcc 
und Vbat nicht garantiert ist.

von G.a.s.t (Gast)


Angehängte Dateien:

Lesenswert?

das ist mein datenblatt, darin steht nichts davon.
der vbat ist doch der 3te pin der über dem Gnd.
sobald ich vbat auf gnd lege steht er wenn ich vbat wieder offen lasse 
zählt er weiter.

von puffel (Gast)


Lesenswert?

G.a.s.t schrieb:
> das ist mein datenblatt, darin steht nichts davon.
> der vbat ist doch der 3te pin der über dem Gnd.
> sobald ich vbat auf gnd lege steht er wenn ich vbat wieder offen lasse
> zählt er weiter.

Schau mal in die aktuelle Version des Datenblatts (Seite 6):
http://datasheets.maxim-ic.com/en/ds/DS1307.pdf

Das ist ja auch logisch. Vbat muss sicher unter Vcc sein, bei 1,25*Vbat 
wird umgeschaltet. Daher muss derPin bei nicht vorhandener Batterie auf 
ein festes Potential deutlich unterhalb von Vcc gebracht werden. Wenn 
keine Batterie drin ist, dann eben auf GND.
Damit funktioniert der DS1307 auch betriebssicher, mit offenem Vbat-Pin 
ist es eher Glückssache.
Falls Dein DS1307 in dem Falle nicht läuft, solltest Du nochmal Deine 
Schaltung prüfen, ob Du da wirklich auf GND gehst...

von Bernd (Gast)


Lesenswert?

Hallo,
warum lassen sich in dem Code von SvenS die Sekunden nicht stellen ?
Weiss das jemand ?

Mit dieser Funktion:
 twi_init();

  twi_start();
  twi_writeadr(DS1307ADR,TW_WRITE);
  twi_writedata(0);  //Register-Pointer
  twi_writedata(0x22);  //sec
  twi_writedata(0x50);  //Minuten
  twi_writedata(0x16);  //Stunden
  twi_writedata(1);  //Tag
  twi_writedata(1);  //Datum
  twi_writedata(1);  //Monat
  twi_writedata(1);  //Jahr
  twi_writedata(0x11);//Control
  twi_stop();
  twi_start();
  twi_writeadr(DS1307ADR,TW_WRITE);
  twi_writedata(0);
  twi_writedata(1);
  twi_stop();


lassen sich nicht die Sekunden auf 22 Stellen sondern immer auf 0?

Im Anhang der komplette Code
1
#include <avr/io.h>
2
#include <util/twi.h>
3
#include <avr/interrupt.h>
4
#include <avr/signal.h>
5
6
#define DS1307ADR 104
7
8
9
void usart_init(void)
10
{
11
  UCSRB = (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
12
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);    //8N1                                
13
  UBRRL  = 103;                  //9600 Baud bei 16MHz
14
}
15
16
void usart_txchar(uint8_t byte)
17
{
18
  while(!(UCSRA & (1 << UDRE)));
19
    UDR=byte;
20
}    
21
22
void usart_txstr(char *str)
23
{
24
  while(*str)
25
  {
26
    usart_txchar(*str);
27
    str++;
28
  }
29
  usart_txchar(10);
30
  usart_txchar(13);
31
}
32
33
void twi_error()
34
{
35
  usart_txstr("TWI-Fehler erkannt");
36
37
}
38
39
void twi_init(void)
40
{
41
42
  TWSR = 0x00;
43
  //TWSR |= (1 << TWPS1) | (1 << TWPS0);  Prescaler=1
44
  TWBR = 152;        // SCL=50KHz @ 16 MHz
45
  //TWCR |= (1 << TWEN);  //TWI aktivieren
46
47
}
48
49
void twi_start(void)
50
{
51
52
  TWCR = (1 << TWSTA) | (1 << TWEN) | (1 << TWINT);
53
  while(!(TWCR & (1 << TWINT)));
54
  if((TWSR & TW_STATUS) != TW_START)
55
  {
56
    usart_txstr("Fehler beim Senden der Start-Condition");
57
    usart_txchar(TWSR);
58
  }
59
}
60
61
void twi_writeadr(uint8_t adr, uint8_t wr)  //W=0 R= alles außer 0
62
{
63
64
  adr=(DS1307ADR << 1);
65
  if(wr)
66
    adr |= 1;    //Beim lesen SLA+R übertragen ansonsten LSB auf 0 lassen (SLA+W)
67
  TWDR=adr;
68
  TWCR = (1 << TWEN) | (1 << TWINT);
69
  while(!(TWCR & (1 << TWINT)));
70
  if ((adr & 1) && ((TWSR & TW_STATUS) != TW_MR_SLA_ACK))
71
    usart_txstr("Fehler beim Senden der Adresse");
72
  if (!(adr & 1) && ((TWSR & TW_STATUS) != TW_MT_SLA_ACK))
73
    usart_txstr("Fehler beim Senden der Adresse");
74
  
75
}
76
77
void twi_writedata(uint8_t data)
78
{
79
  
80
  TWDR=data;
81
  TWCR = (1 << TWEN) | (1 << TWINT);
82
  while(!(TWCR & (1 << TWINT)));
83
  if((TWSR & TW_STATUS) != TW_MT_DATA_ACK)
84
    usart_txstr("Fehler beim Senden der Daten");
85
}
86
87
uint8_t twi_readdata(void)
88
{
89
  uint8_t data;
90
91
  TWCR = (1 << TWEN) | (1 << TWINT);
92
  while(!(TWCR & (1 << TWINT)));
93
  data = TWDR;
94
  return data;
95
  
96
}
97
98
void twi_stop(void)
99
{
100
  
101
  TWCR = (1 << TWEN) | (1 << TWSTO) | (1 << TWINT);
102
  while(TWCR & (1 << TWSTO));
103
  
104
    
105
}
106
107
void ds1307_writereg(uint8_t adr,uint8_t data)
108
{
109
  twi_start();
110
  twi_writeadr(DS1307ADR,TW_WRITE);
111
  twi_writedata(adr);
112
  twi_writedata(data);
113
  twi_stop();
114
}
115
116
117
118
uint8_t ds1307_readreg(uint8_t adr)
119
{
120
  uint8_t data;
121
  
122
  twi_start();
123
  twi_writeadr(DS1307ADR,TW_WRITE);
124
  twi_writedata(adr);
125
  twi_stop();
126
  twi_start();
127
  twi_writeadr(DS1307ADR,TW_READ);
128
  data=twi_readdata();
129
  twi_stop();
130
  return data;
131
}
132
133
void main(void)
134
{
135
  usart_init();
136
  twi_init();
137
    
138
  twi_start();
139
  twi_writeadr(DS1307ADR,TW_WRITE);
140
  twi_writedata(0);  //Register-Pointer 
141
  twi_writedata(0);  //sec
142
  twi_writedata(0x50);  //Minuten
143
  twi_writedata(0x16);  //Stunden
144
  twi_writedata(1);  //Tag
145
  twi_writedata(1);  //Datum
146
  twi_writedata(1);  //Monat
147
  twi_writedata(1);  //Jahr
148
  twi_writedata(0x11);//Control
149
  twi_stop();
150
  twi_start();
151
  twi_writeadr(DS1307ADR,TW_WRITE);
152
  twi_writedata(0);
153
  twi_writedata(1);
154
  twi_stop();
155
  
156
  sei();
157
  
158
  while(1);
159
160
}
161
162
void ds1307_gettime(void)
163
{
164
  uint8_t seconds,minutes,hours;
165
166
  seconds = ds1307_readreg(0);
167
  minutes = ds1307_readreg(1);
168
  hours = ds1307_readreg(3);
169
170
  seconds &= ~128;
171
  usart_txchar((hours >> 4)+0x30);
172
  usart_txchar((hours & 0x0f)+0x30);
173
  usart_txchar(':');
174
  usart_txchar((minutes >> 4)+0x30);
175
  usart_txchar((minutes & 0x0f)+0x30);
176
  usart_txchar(':');
177
  usart_txchar((seconds >> 4)+0x30);
178
  usart_txchar((seconds & 0x0f)+0x30);
179
  usart_txchar(10);
180
  usart_txchar(13);
181
}
182
183
184
SIGNAL (SIG_USART_RECV)
185
{
186
  uint8_t dummy;
187
188
  dummy=UDR;
189
  ds1307_gettime();
190
191
}

von Flasher (Gast)


Lesenswert?

@Bernd
Hab ich mich auch gefragt..
mit der Funktion gings:

ds1307_writereg(0,0x05);

0 sec
1 min
2 hh
...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.