Forum: Mikrocontroller und Digitale Elektronik Ansteuerung DS 1302 (Timekeeping) über I2C-Bus (


von Hölscher (Gast)


Lesenswert?

Hallo Mikrocontroller Freunde

Hat jemand vieleicht ein paar Infos zur Ansteuerung eines
Timekeepingship DS1302 über den I2C-Bus.

z.B 1) Initialisierung des DS1302
    2) Funktion des I2C-Buses

Ich verwende das Flash-Board AT89S8252 und den Compiler von Keil
uVision2 7.0

Ich würde mich sehr über Quellcodeauszüge freuen.

Mit freundlichen Grüßen
Christian Kölscher

von Peter D. (peda)


Lesenswert?

Zum I2C findest Du hier was:

http://www.specs.de/users/danni/appl/hard/i2c/index.htm


RTC-Chips verwende ich normaler Weise keine, die Netzspannung fällt
einfach zu selten aus in Germany. D.h. es reicht der interne Timer des
MC völlig aus.

Nur wenns doch mal mobil sein soll, nehme ich den DS1994. Der ist so
schön unkompliziert, da Batterie gleich mit drin und nur ein Anschluß
benötigt.


Peter

von Hölscher (Gast)


Lesenswert?

Hallo Peter vielen Dank für die schnelle Antwort.

Kannst du mir etwas zu meiner Vorgehensweise zum Anschluss sagen:
Ich habe

1)  3-Anschlüsse des DS1302 (SCLK, I/O, !RST) an den Port3
    (P3_5, P3_4, P3_3)angeschlossen.

Ist das eigentlich egal an welche Ports ich den I2C-Bus anschließe?

Ich würde mich freuen wenn ich eine Bestätigung bekommen würde, dann
kann ich schon mal den Hardware Anschluss als richtig ansehen.

Mit freundlichen Grüßen
Christian

P.S. Ich taste mich so langsam an mein Problem. Ich soll eine
     Steuerung aufbauen mit LCD-Display, Timekeeping DS1302, und
     Termofühler. Habe aber noch nicht so viele Erfahrungen mit der
     Programierung von uC

von Peter D. (peda)


Lesenswert?

"SCLK, I/O, !RST"

Das klingt aber nicht nach I2C, da heißen die Signale SDA und SCL.


Peter

von Hölscher (Gast)


Lesenswert?

Das sind die Pin Bezeichnungen von dem DS1302 Chip.

#define RST   P3_3  // Reset Eingang !RST
#define SDA   P1_0  // Serial Imput Output I/O
#define SCL   P1_1  // Serial Clock SCLK

Auszug aus der Eingebundenen HEADER Datei
Header file for the Atmel AT89S8252.
/*------------------------------------------------
P1 (0x90) Bit Registers
------------------------------------------------*/
sbit P1_0 = 0x90;
sbit P1_1 = 0x91;
sbit P1_2 = 0x92;
sbit P1_3 = 0x93;
sbit P1_4 = 0x94;
sbit P1_5 = 0x95;
sbit P1_6 = 0x96;
sbit P1_7 = 0x97;

sbit T2   = 0x90;       /* External input to Timer/Counter 2, clock out
*/
sbit T2EX = 0x91;       /* Timer/Counter 2 capture/reload trigger & dir
ctl */

sbit SS   = 0x94;       /* SPI: SS - Slave port select input */
sbit MOSI = 0x95;       /* SPI: MOSI - Master data output, slave data
input */
sbit MISO = 0x96;       /* SPI: MISO - Master data input, slave data
sbit SCK  = 0x97;       /* SPI: SCK - Master clock output, slave clock
input */

Vieleicht kannst du da mehr mit anfangen
Mit freundlichen Grüßen
Christian

von Hölscher (Gast)


Lesenswert?

So hat ein wenig länger gedauert,aber...ich kann den chip nicht über den
I2C-Bus ansteuern.

Es sind doch nur drei kleine Leitungen die mich verzweifeln lassen.

Vieleicht kann mir ja jemand helfen..

Quellcode währe sehr schön

Mit freundlichen Grßen
Christian

von Jörg Maaßen (Gast)


Lesenswert?

@Hölcher

Der DS1302 hat garkeine I2C-Schnittstelle sondern eine
SPI-Schnittstelle.

Wenn Du mit I2C arbeiten möchtest dann ist der DS1307 Dein Bauteil.
Selbe Funktion wie DS1302 nur mit I2C-schnittstelle. Dann klappt's
auch mit dem programmieren ;-)

Gruß Jörg

von Hölscher (Gast)


Lesenswert?

Hallo Jörg vielen Dank für die Antwort.
Ich bin zur Zeit dabei den Baustein über SPI anzusteuern.
Hast du vieleicht eine Vorgehensweise für mich oder ein Beispiel zur
Ansteuerung?

Mit freundlichen Grüßen
Christian

von Thomas S. (zeilentrafo)


Lesenswert?

Der DS1302 wird weder mit I2C noch mit SPI angesprochen. Es wird ein 
Drei-Draht-Protokoll verwendet, dessen Knackpunkt ist, dass die 
Antworten der RTC bei der fallenden Flanke anliegen, die zu schreibenden 
Daten jedoch bei der steigenden Flanke der CLK anliegen sollen. Daher 
hat im Datenblatt die Lese-Funktion einen CLK-Impuls weniger.

Hier ist das mal mit den Grundfunktionen Read / Write in Arduino 
umgesetzt. Es läuft auf einem ProMini mit 8 MHz und einen Seeeduino XIAO 
(beide nativ mit 3,3 Volt).

In der Setup-Funktion werden Std. Min und Sekunden gesetzt. Beachte, 
dass hier die Hex-Schreibweise der zweistelligen BCD entspricht.
1
// Three Wire PINS:
2
const int CE = 3;          // Chip Enable
3
const int SCLK = 5;        // Clock
4
const int IO = 4;          // IO-Pin
5
6
// ThreeWireWait
7
const int TWW = 20;        // µSeconds
8
9
void ThreeWireWrite (uint8_t Register, uint8_t Data)  {
10
11
  pinMode (IO, OUTPUT);
12
  digitalWrite (CE, HIGH);
13
  delayMicroseconds (TWW + TWW);
14
15
  for (uint8_t bits = 0; bits < 8; bits ++)  {
16
    digitalWrite (IO, (Register & 1 << bits) ? HIGH : LOW);
17
    delayMicroseconds(TWW / 2);
18
    digitalWrite (SCLK, HIGH);
19
    delayMicroseconds (TWW);
20
    digitalWrite (SCLK, LOW);
21
    delayMicroseconds (TWW);
22
  }
23
24
  for (uint8_t bits = 0; bits < 8; bits ++)  {
25
    digitalWrite (IO, (Data & 1 << bits) ? HIGH : LOW);
26
    delayMicroseconds (TWW / 2);
27
    digitalWrite (SCLK, HIGH);
28
    delayMicroseconds (TWW);
29
    digitalWrite (SCLK, LOW);
30
    delayMicroseconds (TWW);
31
  }
32
  delayMicroseconds (TWW + TWW);
33
  digitalWrite (CE, LOW);
34
}
35
36
37
uint8_t ThreeWireRead (uint8_t Register)  {
38
  uint8_t Data = 0;
39
  pinMode (IO, OUTPUT);
40
  digitalWrite(CE, HIGH);
41
  delayMicroseconds(TWW + TWW);
42
43
  for (uint8_t bits = 0; bits < 8; bits ++)  {
44
45
    digitalWrite(SCLK, LOW);
46
    delayMicroseconds(TWW);
47
    digitalWrite(IO, (Register & 1 << bits) ? HIGH : LOW);
48
    delayMicroseconds(TWW / 2);
49
    digitalWrite(SCLK, HIGH);
50
    delayMicroseconds(TWW);
51
  }
52
53
  pinMode(IO, INPUT);
54
55
  for (uint8_t bits = 0; bits < 7; bits++)  {
56
    delayMicroseconds(TWW / 2);
57
    digitalWrite(SCLK, LOW);
58
    delayMicroseconds(TWW / 2);
59
    Data = (digitalRead(IO)) ? Data | 0x80 : Data;
60
    Data = Data >> 1;
61
    delayMicroseconds(TWW / 2);
62
    digitalWrite(SCLK, HIGH);
63
    delayMicroseconds(TWW / 2);
64
  }
65
66
  digitalWrite(SCLK, LOW);
67
  pinMode (IO, OUTPUT);
68
  digitalWrite (IO, LOW);
69
  delayMicroseconds(TWW + TWW);
70
  digitalWrite (CE, LOW);
71
  return Data;
72
}
73
74
void setup() {
75
76
  // DS1302 Three Wire
77
  pinMode (CE, OUTPUT);
78
  pinMode (SCLK, OUTPUT);
79
  pinMode (IO, OUTPUT);
80
81
  // initial state ThreeWire
82
  digitalWrite (CE, LOW);
83
  digitalWrite (SCLK, LOW);
84
85
  Serial.begin(9600);
86
87
  Serial.println(" ");
88
  Serial.println("DS1302");
89
90
  ThreeWireWrite (0x80, 0x01);   // set Seconds to One
91
  ThreeWireWrite (0x82, 0x45);   // set Minutes to 45
92
  ThreeWireWrite (0x84, 0x21);   // set hrs to 21
93
}
94
95
void loop() {
96
  delay(960);
97
  uint8_t Hours = (ThreeWireRead(0x85));
98
  Serial.print(((Hours >> 4) * 10) + (Hours & 0x0F));
99
  Serial.print(" hrs ");
100
  delay(2);
101
  uint8_t Minutes = (ThreeWireRead(0x83));
102
  Serial.print(((Minutes >> 4) * 10) + (Minutes & 0x0F));
103
  Serial.print(" min ");
104
  delay(2);
105
  uint8_t Seconds = (ThreeWireRead(0x81));
106
  Serial.print(((Seconds >> 4) * 10) + (Seconds & 0x0F));
107
  Serial.println(" Sec");
108
}

: Bearbeitet durch User
von Thomas S. (zeilentrafo)


Lesenswert?

muss die READ-Funktion korrigieren. So wie oben wird das 8. Bit 
unterschlagen. Habe das bemerkt, als die Arbeit mit dem TCS-Register 
begann. Bei den Uhrzeiten war das nicht aufgefallen.

Bitte daher ersetzen mit:
1
uint8_t ThreeWireRead (uint8_t Register)  {
2
  uint8_t Data = 0;
3
4
  pinMode (IO, OUTPUT);
5
  digitalWrite(CE, HIGH);
6
  delayMicroseconds(TWW + TWW);
7
8
  for (uint8_t bits = 0; bits < 8; bits ++)  {
9
10
    digitalWrite(SCLK, LOW);
11
    delayMicroseconds(TWW);
12
13
    digitalWrite(IO, (Register & 1 << bits) ? HIGH : LOW);
14
    delayMicroseconds(TWW / 2);
15
    digitalWrite(SCLK, HIGH);
16
    delayMicroseconds(TWW);
17
  }
18
19
  pinMode(IO, INPUT);
20
21
  for (uint8_t bits = 0; bits < 8; bits++)  {
22
23
    delayMicroseconds(TWW / 2);
24
    digitalWrite(SCLK, LOW);
25
    delayMicroseconds(TWW / 2);
26
27
    Data = (digitalRead(IO)) ? (Data >> 1) | 0x80 : Data >> 1;
28
29
    delayMicroseconds(TWW / 2);
30
    digitalWrite(SCLK, HIGH);
31
    delayMicroseconds(TWW / 2);
32
  }
33
34
  digitalWrite(SCLK, LOW);
35
  pinMode (IO, OUTPUT);
36
  digitalWrite (IO, LOW);
37
  delayMicroseconds(TWW + TWW);
38
  digitalWrite (CE, LOW);
39
  return Data;
40
}

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Thomas S. schrieb:
> Beachte,
> dass hier die Hex-Schreibweise der zweistelligen BCD entspricht.

Ich schätze dass sich der TO nach 18(!) Jahren nicht mehr für deinen 
Beitrag interessiert....

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.