RV3029 Echtzeituhr am Arduino
Ein grosser Vorteil der Arduino-Bibliothek ist es ja, dass man komplizierte Hardware-nahe Programmierung nicht mehr selbst erledigen muss, sondern auf vorgefertigte Libraries zurückgreifen kann, die einem diese Arbeit abnehmen.

Als kleines Beispiel für diese Funktionen sei hier die Ansteuerung eines RV3029 Echtzeituhren-Bausteins mittels der Wire-Bibliothek gezeigt.

Der Integrierte Schaltkreis RV3029 beinhaltet eine vollständige Uhr (RTC), komplett mit digital temperaturkompensiertem Quarzoszillator sowie umfangreichen Timer und Alarmfunktionen. Das ganze ist in einem nur 6*3mm grossen SMD Keramikgehäuse untergebracht.

Angesteuert wird dieser Baustein mit dem bekannten I2C protokoll.

Die Implementierung des I2C Protokolls verbirgt sich in der Arduino-Bibliothek Wire.h, welche am Anfang des Quellcodes mit einer #include Direktive eingebunden wird.

Danach steht das Wire-Objekt zur Verfügung, welches mit seinen Methoden die Kommunikation mit I2C Komponenten ermöglicht.

An einem I2C Bus können viele verschiedene Bausteine angeschlossen werden, und so benötigt jeder einzelne dieser Bausteine eine Adresse, die sich im Datenblatt findet.

Hier ergibt sich ein erster böser Stolperstein.

Üblicherweise wird die I2C-Adresse als 8Bit Zahl angegeben, wobei das niederwertigste Bit bestimmt, ob vom Baustein gelesen oder ob der Baustein beschrieben werden soll.

Die Arduino-Bibliothek hingegen betrachtet die I2C Adresse als 7 Bit Zahl, so dass die Adresse aus dem Datenblatt erst halbiert werden muss.

Diesem Umstand wird dadurch Rechnung getragen, dass die Adresse am Anfang in einer #define Direktive korrekt angelegt wird. Abgesehen davon funktioniert der Zugriff dann recht problemlos.

Zum Beispiel werden mit diesen Kommandos zwei Bytes ab Adresse 02 in den Uhrenbaustein geschrieben, was die Interrupts deaktiviert und das Statusregister des Bausteins löscht.

Wire.beginTransmission(RV3029);
Wire.write(0x02);
Wire.write(0x00);
Wire.write(0x00);
Wire.endTransmission();

Dieses wird in der startup-Sektion des Codes erledigt.

Die Hauptschleife loop() des Programms wartet dann auf eine Benutzereingabe über die serielle Konsole.

Wird ein '?' empfangen, antwortet es mit dem aktuellen Datum und der Uhrzeit.

Zudem kann die Uhr mit dem Befehl 'set dd.mm.yy hh:mi:ss' auf einen anderen Wert gesetzt werden.

Hier findet sich der komplette Sketch zum Download.

#include <Wire.h>

#define RV3029 0xac/2
#define STR2BCD_ERROR 0xff

void setup() {
Wire.begin();

Serial.begin(9600);
Serial.println("RV3029 Arduino Clock.");
Wire.beginTransmission(RV3029);
Wire.write(0x02);
Wire.write(0x00);
Wire.write(0x00);
Wire.endTransmission();
}

void loop () {
String data;
byte tag,monat,jahr,stunde,minute,sekunde;

data=Serial.readStringUntil('\n');

if(!data.compareTo("?")) rv3029_print();
if (data.length()==21) {
if (!data.substring(0,3).compareTo("set")) {
Serial.println("Set Clock");
tag=str2bcd(data[4],data[5]);
monat=str2bcd(data[7],data[8]);
jahr=str2bcd(data[10],data[11]);
stunde=str2bcd(data[13],data[14]);
minute=str2bcd(data[16],data[17]);
sekunde=str2bcd(data[19],data[20]);
Wire.beginTransmission(RV3029);
Wire.write(0x08);
Wire.write(sekunde);
Wire.write(minute);
Wire.write(stunde);
Wire.write(tag);
Wire.write(0x00);
Wire.write(monat);
Wire.write(jahr);
Wire.endTransmission();
rv3029_print();

}
}


}

void rv3029_print() {


byte data[8];

byte index=0;


Serial.println("RV3029 Time:");

Wire.beginTransmission(RV3029);
Wire.write(0x08);
Wire.endTransmission();


Wire.requestFrom(RV3029, 8);

while(Wire.available())
{
data[index] = Wire.read();
index=(index++)&0x07;

}
printhex(data[3]);

Serial.print(".");
printhex(data[5]);
Serial.print(".");
printhex(data[6]);
Serial.print(" ");
printhex(data[2]);
Serial.print(":");
printhex(data[1]);
Serial.print(":");
printhex(data[0]);
Serial.println();
}


byte str2bcd(char data1,char data2) {

if (data1>'9') return STR2BCD_ERROR;
if (data1<'0') return STR2BCD_ERROR;
if (data2>'9') return STR2BCD_ERROR;
if (data2<'0') return STR2BCD_ERROR;

return ((data1-0x30)<<4)+(data2-0x30);

}

void printhex(byte data) {
char buffer[4];
sprintf(buffer,"%02x",data);
Serial.print(buffer);
}

Insgesamt unterscheidet sich die Benutzung des I2C Busses in einem Arduino-Sketch also nicht wirklich von derjenigen mit einer anderen I2C Bibliothek mit C auch. Eine Nähere Beschreibung findet sich natürlich auf der Arduino Homepage unter http://www.arduino.cc/en/Reference/Wire

Bauteile für dieses Projekt - Anzeigen:
Aktive Bauelemente

Passive Bauelemente


Weitere Informationen,Grundlagen,Bauanleitung,Schaltplan, Links zum Thema
Anzeigen:

Neueste Artikel
Anzeigen:
Aktuelle Newsbeiträge
Sie sind Besucher Nr. 1213909