LTC6995 – Long Timer, Low Frequency Oscillator

Über den Beitrag

Was bringt euch ein LTC6995? Die internen Timer der AVR Microcontroller haben eine begrenzte, maximale Laufzeit. Je nach Modell und Taktung liegt diese Zeit im Sekundenbereich, für manche Timer auch weniger. Wollt ihr längere Zeiträume abdecken, müsst ihr zusätzliche Zähler einführen. Das hatte ich zum Beispiel in meinen Beiträgen über die Timer0/2, Sleep Modes und Watchdog Timer behandelt.

Ich habe mich deshalb gefragt, ob es nicht externe Zeitgeber bzw. Oszillatoren gibt, die im Bereich von Minuten oder sogar Stunden arbeiten – und mit dem LTC6995 bin ich fündig geworden. Er umfasst einen Frequenzbereich 977 Hertz bis hinunter zu 29.1 Mikrohertz oder – in Perioden ausgedrückt – von ca. einer Millisekunde bis 9.54 Stunden. 

Folgende Themen behandele ich in diesem Beitrag:

Technische Eigenschaften des LTC6995

Bauform und Versionen

Der LTC6995 - leider nicht als "DIP" erhältlich
Der LTC6995 – rechts: aufgelötet auf einen Adapter (ich hatte nur einen mit 10 Pins vorrätig)

Zuerst die schlechte Nachricht für alle Breadboard Entwickler: es gibt den LTC6995 nicht in „DIP“-Ausführung, sondern nur als SMD Bauteil, nämlich als TSOT23 oder als DFN. Wenn ihr ihn auf dem Breadboard verwenden wollt, dann müsst ihr ihn auf einen Adapter löten. Sucht einfach nach „SOT23 Adapter“, z.B. bei Amazon. Das Auflöten von SMD Bauteilen ist natürlich eine gewisse Herausforderung, aber machbar. Eine Anleitung habe ich hier gefunden.

Es gibt zwei Versionen des LTC6995 und zwar den LTC6995-1 und den LTC6995-2. Auf die Unterschiede gehe ich noch ein. Ich habe die „-1 Version“ für diesen Beitrag verwendet, gehe aber auch auf die „-2 Version“ ein.

Darüber hinaus finden sich in der Teilecodierung weitere Buchstaben, so habe ich beispielsweise den LTC6995CS6-1#TRMPBF. Das „C“ steht für den Temperaturbereich, das „S6“ für die TSOT23 Bauform und TRMPBF für die Verpackung (Tape and Reel Mini). Näheres findet ihr im Datenblatt. Kaufen könnt ihr den LTC6995-1 z.B. bei ebay oder bei Conrad für ca. 3 Euro plus Versand. Der LTC6995-2 ist schwerer zu bekommen. Mouser wäre eine Quelle, allerdings müsst ihr dort 20 Euro Versandgebühren bezahlen. Das lohnt natürlich nur bei größeren Bestellungen. 

Alternativ gibt es den LTC6995 auch auf einem Entwicklungs- / Demostrationsboard namens DC1562B-M. Aber das ist sicherlich nur etwas, wenn man richtig viel mit dem LTC6995 vor hat. 

Technische Daten

  • Periode: 1 Millisekunde bis 9.5 Stunden
  • Versorgungsspannung: 2.25 – 5.5 Volt
  • wird mit nur drei Widerständen konfiguriert
  • (Start-)Output Polarität wählbar
  • maximaler Ouput Strom (oder Senke): 20 Milliampere 
  • Stromverbrauch: 55 – 80 Mikroampere
  • 500 Mikrosekunden Start-Up Zeit

Pinout des LTC6995

Pinout des LTC6995
Pinout des LTC6995
  • VCC/GND: Spannungsversorgung
  • OUT: Output Signal
  • SET: hier wird die Frequenz eingestellt. Der LTC6995 regelt SET auf 1 Volt. Über einen Widerstand wird SET mit GND verbunden. Der Stromfluss von SET nach GND bestimmt die Frequenz. Mit anderen Worten: die Größe des Widerstandes bestimmt die Frequenz. 
  • DIV: über die hier anliegende Spannung wird der Teiler (Divider) festgelegt, durch den die an SET festgelegte Frequenz geteilt wird. Es stehen acht Teiler zur Verfügung: 20, 23, 26, … , 221. Zusätzlich wird an DIV die Startpolarität des Output Signals eingestellt. Acht Teiler mit zwei möglichen Startpolaritäten ergibt 16 Einstellungen. Um diese Einstellungen vornehmen zu können, sitzt hinter dem DIV Pin ein 4-Bit A/D-Wandler.  
  • RST: der Resetpin startet den Timer neu. Beim LTC6995-1 ist der Pin active-high, beim LTC6995-2 ist er active-low.

Der LTC6995 als Oszillator

LTC6995-1 Oszillatorschaltung
LTC6995-1 Oszillatorschaltung

Die Oszillatorschaltung ist sehr einfach. RST kommt beim LTC6995-1 an GND, beim LTC6995-2 an VCC. RSET stellt die Frequenz ein. Die Spannung an DIV wird über einen Spannungsteiler (R1 und R2) eingestellt. Der Kondensator C1 dient der Stabilisierung der Versorgungsspannung. An OUT erhaltet ihr ein Rechtecksignal mit der gewünschten Frequenz. Zum Spielen könnt ihr z.B. eine LED dranhängen (bis 20 mA).

Auswahl der Widerstände

Überlegt euch zunächst, wie euer Rechtecksignal aussehen soll. Soll es beim Einschalten und Resetten HIGH oder LOW sein? Zur Veranschaulichung: 

OUT Signal in Abhängigkeit der Größe R1 vs. R2
OUT Signal in Abhängigkeit der Größe R1 vs. R2

Dann wählt ihr den passenden Divcode aus Tabelle 1. Die Divcodes 0 – 7 sorgen für eine Startpolarität LOW (0), 8 – 15 für die Startpolarität HIGH (1). Jetzt prüft ihr, welcher Divcode die von euch gewünschte Periode (tOUT) abdeckt. Die Bereiche überlappen sich. Für den geringsten Stromverbrauch (an SET) wählt ihr immer den geringstmöglichen Teiler NDIV.

Tabelle 1: Divcode und RSET-Berechnung für den LTC6995
Tabelle 1: Divcode und RSET-Berechnung für den LTC6995

Die Tabelle 1 bzw. der Divcode gibt euch die Werte für R1 und R2 vor. Die Vorgaben sind Idealwerte und zum Teil recht ungewöhnlich. Ihr könnt euch durch Hintereinanderschalten von üblichen Widerständen behelfen. Kleinere Abweichungen sind kein Problem, Hauptsache ihr kommt nicht in die benachbarten Divcodes. 

RSET und tOUT hängen folgendermaßen zusammen:

In der Tabelle 1 findet ihr in der letzten Spalte die vorausgefüllte Formel für RSET, in die ihr nur noch tOUT einfügen müsst. Die Formel enthält 1/2 tOUT, da dieser Wert für die meisten Anwendungen relevant ist, wie ihr noch sehen werdet.

Praktische Überprüfung einiger Werte

Ich habe mal ein paar Kombinationen ausprobiert und kam auf die folgenden Ergebnisse:

Tabelle 2: LTC6995 als Oszillator -praktische Beispiele
Tabelle 2: LTC6995 als Oszillator -praktische Beispiele

Die Zeiten im Sekundenbereich habe ich ermittelt, indem ich eine LED an OUT gehängt und zehn bis 20 Zyklen mit der Stoppuhr gemessen habe. Zur Prüfung der ersten Widerstandskombination in Tabelle 2 habe ich ein Oszilloskop verwendet. Auch in diesem Grenzbereich zur maximalen Frequenz lieferte der LTC6995 es ein sauberes Rechtecksignal:

OUT-Signal des LTC6995 im Millisekundenbereich
OUT-Signal des LTC6995 im Millisekundenbereich

Der LTC6995 als Power-On Reset Timer

Was bedeutet Power-On Reset?

Beim Einschalten der Versorgungsspannung von Schaltungen dauert es unter Umständen ein wenig bis sich die Spannung stabilisiert hat. In dieser Startphase mit undefinierten Bedingungen könnten komplexe Bauteile wie Microcontroller und Computer unvorhergesehene Dinge tun. Deshalb haben sie interne Power-On Reset (POR) Schaltungen integriert. Solange das System noch nicht die erforderliche Mindestspannung hat, werden die empfindlichen Teile im Reset gehalten. Systeme, die kein POR haben, können mit externen PORs ausgestattet werden. Hierfür eignet sich der LTC6995. Auch wenn euch PORs nicht interessieren, lest trotzdem weiter, denn die noch folgenden Schaltungen bauen zum Teil darauf auf.  

Die Schaltung

Der LTC6995 als POR
Der LTC6995 als POR

Der Unterschied der POR Schaltung zur Oszillatorschaltung besteht lediglich darin, dass SET nicht mit GND, sondern mit OUT verbunden ist. Für die Divcodes 0-7 ist OUT zu Beginn LOW. Systeme, die LOW resettet werden, können so im Reset Modus gehalten werden. Nach 1/2 tOUT geht OUT auf HIGH und das kontrollierte System startet.

Ist OUT im HIGH Zustand, fließt kein Strom mehr über SET ab. Ihr erinnert euch vielleicht, dass SET auf 1 Volt eingeregelt ist. Da der Timer über den an SET abfließenden Strom gesteuert wird, wird der Timer gestoppt, so dass kein weiteres Reset Signal erzeugt werden kann. 

LTC6995 als POR - OUT Signal
LTC6995 als POR – funktioniert nur mit R1>R2

Mit OUT = HIGH zu starten, also Divcode 8-15, würde nicht funktionieren, da der Timer sofort stoppt. Für ein System, das mit einem HIGH Signal resettet wird, muss das OUT Signal deshalb invertiert werden. 

Signalinvertierung

Ein Signal bzw. ein Logiklevel könnt ihr sehr einfach mit einem NPN Transistor (z.B. BC547) und zwei Widerständen invertieren:

Einfache Schaltung zum Invertieren von Signalen bzw. Logikleveln
Einfache Schaltung zum Invertieren von Signalen bzw. Logikleveln

Ist das Input Level LOW bzw. GND, dann ist der Transistor geschlossen und das Output Level HIGH bzw. auf VCC Niveau. Ist das Input Level HIGH, ist der Transistor offen und das Output Level wird auf LOW bzw. GND gezogen.

Allgemeiner Timer

Der POR Timer hat seine Schuldigkeit getan, wenn das System läuft. Einen allgemeinen Timer möchtet ihr hingegen mehrfach verwenden. Dazu muss der LTC6995 leglich resettet werden können.

Am LTC6995-1 wird RST dazu über einen Pull-Down Widerstand mit GND verbunden und kann dann mit einem HIGH Signal neu gestartet werden. Beim LTC6995-2 ist es das Gleiche, nur mit umgekehrten Polaritäten (RST an HIGH und Reset durch LOW).

In der folgenden Schaltung wird ein Taster zum Resetten benutzt: 

Zurücksetzbarer Timer
Zurücksetzbarer Timer

Damit könnt ihr euch zum Beispiel – ohne Microcontroller – eine Lampe bauen, die sich nach einer bestimmten Zeit abschaltet (oder einschaltet). Oder ihr verwendet anstelle des Tasters den Ausgang eines Sensors und OUT löst auf dessen Signal hin eine Reaktion aus. Gegebenenfalls müsst ihr das OUT-Signal dazu noch invertieren.

Der LTC6995 als Sleep Mode Wecker

In meinem letzten Beitrag hatte ich gezeigt, wie man einen ATmega328P oder einen anderen Microcontroller per externem Interrupt aus dem Schlafmodus wecken kann. Mit dem LTC6995 erhaltet ihr die Möglichkeit, den Microcontroller ungestört über lange Zeiträume schlafen zu lassen.

Die Schaltung

Für den Sleep Mode Wecker verwenden wir die Schaltung von eben und ersetzen den Taster durch einen I/O Pin des ATmega328P (hier PD6). OUT verbinden wir mit einem Interruptpin (hier INT0). 

LTC6995 als Sleep Mode Wecker für den ATmega328P
LTC6995 als Sleep Mode Wecker für den ATmega328P

Und am Arduino UNO sieht das so aus:

 LTC6995 als Sleep Mode Wecker für den Arduino UNO
LTC6995 als Sleep Mode Wecker für den Arduino UNO

Ein Beispielsketch

Genau genommen kommen jetzt zwei Beispielsketche, sie machen aber dasselbe. Der erste ist in C gehalten, der zweite „in Arduino“. Ein paar Anmerkungen zu den Sketchen:

  • Zunächst wird die Sleep Headerdatei eingebunden.
  • PD6 und PD7 (=Arduino UNO Pin 6 und 7) werden auf Output gesetzt.
  • Ein Interrupt an INT0 (=Arduino UNO Pin 2) wird eingerichtet; ausgelöst wird er mit der steigenden Flanke.
  • Am Beginn der Loop Schleife leuchtet die LED an PD7 für eine Sekunde – das ist unser Hallo-ich-bin-wach-Zeichen.
  • Bevor der ATmega328P (bzw. der Arduino UNO) in den Schlaf geschickt wird, wird der Interrupt aktiviert und der LCT6995 resettet.
  • Der LCT6995 schickt nach 1/2 tOUT sein Wecksignal.
  • Die Interruptroutine deaktiviert den externen Interrupt.

Wenn ich hier nochmal im Detail auf die Sleep Modes eingehen würde, würde das den Rahmen des Beitrages sprengen. Schaut ggf. in meinen letzten Beitrag

#include <avr/sleep.h>

void setup(){
  DDRD = (1<<PD7)|(1<<PD6); // PD6 und PD7 auf OUTPUT
  EICRA |= (1<<ISC01)|(1<<ISC00); // interrupt on rising edge of INT0
}

void loop(){
  PORTD |= (1<<PD7); // switch on LED
  _delay_ms(1000);
  PORTD &= ~(1<<PD7); 
  EIMSK |= (1<<INT0); // external interrupt enable on INT0
  resetLTC6995();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // choose power down mode
  sleep_mode(); // sleep now!
}

void resetLTC6995(){
  PORTD |= (1<<PD6);  // Reset Signal für den LTC6995-1
  _delay_ms(1);
  PORTD &= ~(1<<PD6);
}

// INT0 interrupt service routine
ISR(INT0_vect){ 
  EIMSK &= ~(1<<INT0); // external interrupt disable (INT0)
}

 

#include <avr/sleep.h>
const int ledPin = 7;
const int ltc6995ResetPin = 6;

void setup(){
  pinMode(ledPin, OUTPUT);
  pinMode(ltc6995ResetPin, OUTPUT);
}

void loop(){
  digitalWrite(ledPin, HIGH); // switch on LED
  delay(1000);
  digitalWrite(ledPin, LOW);
  attachInterrupt(digitalPinToInterrupt(2), intRoutine, RISING); //enable interrupt
  resetLTC6995();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // choose power down mode
  sleep_mode(); // sleep now!
}

void resetLTC6995(){
  digitalWrite(ltc6995ResetPin, HIGH); // Reset Signal für den LTC6995-1
  delay(1);
  digitalWrite(ltc6995ResetPin, LOW);
}

// interrupt routine
void intRoutine(){ 
  detachInterrupt(2); // disable interrupt
}

 

Der LTC6995 als externer Watchdog Timer

Ich werde nicht noch einmal darauf eingehen, was ein Watchdog ist und wozu man ihn braucht. Falls nötig schaut hier

Die Grundidee ist folgende: Der LTC6995 sendet regelmäßig ein Resetsignal zum überwachten System, es sei denn, das überwachte System resettet den LTC6995 vorher.

Zunächst habe ich dabei einen blöden Fehler gemacht, den ich mit euch teilen möchte. Ich dachte mir, ich könne einfach das Oszillatorsignal des LTC6995 zum Resetten benutzen. Divcode 8-15, dann ist OUT zu HIGH und wenn OUT auf LOW geht, gibt’s ein RESET. Stimmt auch soweit, nur bleibt OUT für weitere Zeitspanne von 1/2 tOUT auf LOW. Das bedeutet, dass der Microcontroller solange nicht resettet und dass das Resetsignal nicht abgestellt werden kann. Ich hoffe ihr könnt mir noch folgen…

Die Lösung: Self-Reset des LTC6955

Mit der folgenden Schaltung geht der LTC6995-1 nach 1/2 tOUT kurz auf HIGH und resettet dann. Das funktioniert aber nur mit den Divcodes 0-7. Das Beispiel mit diesen Werten stammt aus dem Datenblatt. 

Self-Reset Schaltung
Self-Reset Schaltung

Bei Verwendung des LTC6995-2 verwendet ihr dieselbe Schaltung, aber die Divcodes 8-15. Der Verlauf an OUT sieht folgendermaßen aus (nicht maßstabsgetreu!):

OUT Signal für die Self-Reset Schaltung

tpulse wird für den LTC6995-1 nach folgender Formel berechnet (Details im Datenblatt):

Mit RPW = 2.26 kOhm und CPW = 470 pF ergibt sich ein tpulse von 1 µs. 

Da der ATmega328P bzw. der Arduino UNO oder andere AVR MCUs mit einem LOW-Signal resettet werden, muss das OUT Signal bei Verwendung des LTC6995-1 noch invertiert werden. Die Schaltung sieht dann so aus (RPW und CPW habe ich geändert, da ich die Größen nicht vorrätig hatte): 

Watchdog Timer Schaltung für den ATmega328P
Watchdog Timer Schaltung für den ATmega328P

Ein Beispielsketch

Zum Test des nun folgenden Beispielsketches habe ich in der Schaltung folgende Widerstände gewählt:

  • R1 = 994 kOhm
  • R2 = 395 kOhm
  • RSET = 218,1 kOhm

Das entspricht Divcode 4 und 1/2 tOUT ca. 9,15 Sekunden. Nach einem Reset des LTC6995-1 hat man in dieser Konfiguration also 9,15 Sekunden um ihn erneut zu resetten, sonst resettet der LTC6995-1 den Microcontroller. Ein Resetwettlauf, sozusagen. 

Der Beispielsketch (wieder einmal in C und einmal „in Arduino“) macht folgendes:

  • PD6 und PD7 (bzw. Arduino Pin 6 und 7) werden auf OUTPUT gestellt
  • Die LED an PD7 leuchtet als Zeichen für den Start des Sketches für eine Sekunde
  • Bevor es in die Loop Schleife geht, wird der LTC6995-1 noch einmal resettet (watchdogReset())
  • ist der Watchdog Reset wie hier auskommentiert, wird der ATmega328P immer wieder nach 9,15 Sekunden durch den LTC6995-1 resettet, was ihr am Leuchten der LED erkennt
  • wenn ihr den Watchdog Reset entkommentiert, findet kein Reset des ATmega328P statt – die LED bleibt aus
void setup(){
  DDRD = (1<<PD7)|(1<<PD6);
  PORTD |= (1<<PD7);
  _delay_ms(1000);
  PORTD &= ~(1<<PD7);
  watchdogReset();
}

void loop(){
//  _delay_ms(8000);
//  watchdogReset();
}

void watchdogReset(){
  PORTD |= (1<<PD6);
  _delay_ms(1);
  PORTD &= ~(1<<PD6);
}

 

const int ledPin = 7;
const int wdResetPin = 6;

void setup(){
  pinMode(ledPin, OUTPUT);
  pinMode(wdResetPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin,LOW);
  watchdogReset();
}

void loop(){
//  delay(8000);
//  watchdogReset();
}

void watchdogReset(){
  digitalWrite(wdResetPin,HIGH);
  delay(1);
  digitalWrite(wdResetPin,LOW);
}

 

3 thoughts on “LTC6995 – Long Timer, Low Frequency Oscillator

  1. Hallo Wolle,
    sehr schöner Beitrag, diesen Baustein habe ich gesucht, Danke.
    Was für ein RIGOL-Oszilloskop verwendest Du da?

    Gruß
    Wölle

    1. Hi Wölle, danke für’s Feedback. Ich habe ein Rigol DS1054Z. Gekauft bei Conrad. Ich bin ganz zufrieden damit. Schöne Grüße, Wolle

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.