Pfad: Home => AVR-Übersicht => Anwendungen => ATtiny mit Quarzen takten
Tiny XTAL oscillator Anwendungen von
AVR-Einchip-Prozessoren AT90S, ATtiny, ATmega und ATxmega
Einen ATtiny mit einem Quarz takten
Logo

ATtiny mit Quarz

Eine einfache Aufgabe: ein ATtiny soll statt mit dem internen ungenauen RC-Oszillator mit einem externen Quarz getaktet werden. Eigentlich eine einfache Aufgabe. Aber dabei gibt es viele Hürden und Dinge, die man falsch machen kann oder die nicht funktionieren. Daher hier einige Hinweise, wie man es macht.

CMOS-Version des Quarzteilers Und so sähe so ein Quarzteiler für einen 15 MHz-Quarz durch 68 in der CMOS-Ausführung aus: Insgesamt wären hier drei 14-polige ICs nötig und insgesamt 42 Anschlüsse zu verdrahten.

Dagegen passt die Version mit einem ATtiny25-Mikrocontroller in ein einziges achtpoliges IC, bei dem nur ganze sieben Pins zu verdrahten sind. Der ganze Rest steckt in den Prozessorinnereien, die mit ein paar lumpigen Zeilen Programm dazu gebracht wird, die gesamte Aufgabe zu erledigen.

1 Einen quarzgenauen Rechteckgenerator bauen

Aufgabenstellung ist es, einen quarzgenauen Taktgenerator zu bauen. Das geht im Prinzip ganz einfach:
  1. Den ATtiny mit einem Quarz takten.
  2. Den internen Timer/Counter in den CTC-Modus (Clear Timer on Compare) bringen).
  3. In das Vergleichsregister des Timers (bei einem 8-Bit-Timer: Compare A, bei einem 16-Bit-Timer entweder in Compare A oder in das Interrupt Capture Register ICR) einen Vergleichswert schreiben.
  4. Die Ausgänge OCnA und/oder OCnB beim Compare Match torkeln lassen.
  5. Die Ausgänge OCnA und/oder OCnB als Ausgänge einstellen.
Und schon ist der schöne Rechteckgenerator fertig.

Damit lassen sich aus einem Quarz ganz famose Frequenzen zaubern. Und alles sehr flexibel. Mit dem OpenOffice-Rechensheet hier lässt sich für alle handelsüblichen Quarze Zellen mit "-" kennzeichnen unmögliche Kombinationen.

Enthält die Zelle E6 bzw. J6 0,00, dann ist mindestens ein Quarz in der Lage, genau diese Frequenz zu erzeugen. Welcher das ist, kann man an den grün eingefärbten Deltas in den Spalten E bzw. J sehen. Quarze, die weniger als 0,1% vom Sollwert abweichen, sind gelb hinterlegt.

Man beachte noch, dass der CTC-Div-Wert um Eins verringert werden muss, bevor er in das oder die Compare-Register geschrieben werden kann.

2 Die Hardware

Schaltbild des Quarzteilers Das ist schon die ganze Hardware. Die zwei Keramikkondensatoren von 18 pF sind zum Anschwingen des Oszillators zwingend.

Das Ausgangssignal kann an PB0 (OC0A) und, wenn das so gewünscht und programmiert ist, an PB1 (OC0B) entnommen werden. Beide können auch gegenphasig sein oder gegenseitig verschoben sein.

In der Praxis hat sich gezeigt, dass der Taktoszillator mit einem Quarz von 15 MHz bei einer Betriebsspannung oberhalb von 4 V nicht anspringt bzw. nach wenigen Takten seinen Betrieb wieder einstellt. Es hilft auch nicht, XTAL2 mit einem Widerstandsteiler zu teilen. Läuft der Oszillator, kann die Betriebsspannung sukzessive auf bis zu 5,5 V erhöht werden, ohne dass er aussetzt. Braucht man also Betriebsspannungen über 4 V, muss man die Betriebsspannung z. B. mit einem Widerstand, einer Zenerdiode und einem Elko auf 3,3 oder 2,7 V heranbsetzen oder eine andere Behelfslösung wählen.

Noch ein Hinweis zum Ziehen des Quarzes mit einem Trimmer. Das funktioniert am XTAL1-Eingang. Aber nicht zu viel erwarten, es können nur wenige kHz gezogen werden, und zwar nach oben. Und: nicht zu viel, dann startet der Quarzoszillator beim Anlegen der Betriebsspannung nicht.

3 Umstellung der Fuses

Damit der ATtiny mit dem externen Quarz als Taktgeber arbeitet, müssen die folgenden Fuses verstellt werden:
  1. CLKOUT muss in jedem Fall eingeschaltet werden!
  2. CLKDIV8 muss ausgeschaltet werden, es sei denn man möchte mit einem Achtel des Quarztaktes den Takt antreiben.
  3. CLKSEL muss entweder auf einen Low-Speed-Quarz (z. B. mit 32,768 kHz) gesetzt oder man wählt einen passenden externen Quarztaktgeber als Quelle aus. Durch das Einschalten von CLKOUT ist sichergestellt, dass der externe Quarz wie ein Quarzoszillator arbeitet, da er von CLKOUT angestoßen wird. Lassen Sie sich also von den fehlenden Auswahlmöglichkeiten im Studio nicht zu der Annahme verleiten, der tiny könne nur mit Low-Speed-Quarzen arbeiten (ich bin da schon drauf reingefallen!).
Achtung bei 32,768 kHz-Quarzen. Nach der Umstellung kann man den Tiny nur noch mit weniger als 8 kHz über ISP ansprechen. Hat man die CLKDIV8-Fuse versehentlich eingeschaltet, nur noch mit weniger als 1 kHz. AVRISP-MkII-Clones können das, STK500-Clones nicht! Das Studio weigert sich, Flash oder EEPROM mit weniger als 5 kHz zu programmieren.

4 Software und Downloads

Die Software gibt es im Assemblerformat hier zum Download. Das Listing gibt es weiter unten.

Zusätzlich gibt es noch folgenden OpenOffice-Dokumente zum Download: Der Quellcode:

;
; *********************************
; * Xtal oscillator with ATtiny25 *
; * (C)2019 by DG4FAC             *
; *********************************
;
.nolist
.include "tn25def.inc" ; Define device ATtiny25
.list
;
; **********************************
;         H A R D W A R E
; **********************************
;
; Device: ATtiny25, Package: 8-pin-PDIP_SOIC
;
;            _________
;         1 /         |8
; RESET o--|RESET  VCC|--o +5 V
; XTAL1 o--|PB3    PB2|--o
; XTAL2 o--|PB4    PB1|--o Osc out 2
;   0 V o--|GND    PB0|--o Osc out 1
;         4|__________|5
;
;
; **********************************
;  A D J U S T A B L E   C O N S T
; **********************************
;
.equ clock = 15000000 ; 15 MHz, your xtal frequency
.equ fOut = 100 ; Your desired frequency
.equ cClkPresc = 1 ; Your clock prescaler value 
.equ cUseOC0B = 1 ; Use OC0B as reverse output
;
; **********************************
;   F I X E D   C O N S T A N T S
; **********************************
;
; Derive prescaler value from clock and frequency
.if (clock/fOut/cClkPresc/2)<=256
  .equ cPresc=1
  .equ cCsPresc=1
  .else
  .if (clock/fOut/cClkPresc/2/8)<=256
    .equ cPresc=8
    .equ cCsPresc=2
    .else
    .if (clock/fOut/cClkPresc/2/64)<=256
      .equ cPresc=64
      .equ cCsPresc=3
      .else
      .if (clock/fOut/cClkPresc/2/256)<=256
        .equ cPresc=256
        .equ cCsPresc=4
        .else
        .if (clock/fOut/cClkPresc/2/1024)>256
          .error "Desired frequency too low!"
          .else
          .equ cPresc=1024
          .equ cCsPresc=5
          .endif
        .endif
      .endif
    .endif
  .endif
;
; Derive divider and compare value
.equ divider = (((((clock+fout/2)/fOut+cClkPresc/2)/cClkPresc+cPresc/2)/cPresc)+1)/2
.equ cCtc = divider - 1 ; CTC value
;
; **********************************
;        R E G I S T E R S
; **********************************
;
.def rmp = R16 ; Multipurpose register
;
; **********************************
;  M A I N   P R O G R A M   I N I T
; **********************************
;
.cseg
.org 000000
;
Main:
  sbi DDRB,DDB0 ; PB0 direction output
  cbi PORTB,PORTB0 ; Clear OC0A output
  ldi rmp,cCtc ; Write CTC value
  out OCR0A,rmp ; to compare register A
  .if cUseOC0B == 1
    sbi DDRB,DDB1 ; PB1 direction output
    sbi PORTB,PORTB1 ; Set OC0B output
    out OCR0B,rmp ; and B
    ldi rmp,(1<<WGM01)|(1<<COM0A0)|(1<<COM0B0) ; CTC mode, toggle OC0A and OC0B
    .else
    ldi rmp,(1<<WGM01)|(1<<COM0A0) ; CTC mode, toggle OC0A
    .endif
  out TCCR0A,rmp ; in TC0 control port A
  ldi rmp,cCsPresc ; Prescaler setting
  out TCCR0B,rmp ; in TC0 control port B
  ldi rmp,1<<SE ; Sleep enable, idle mode
  out MCUCR,rmp
Loop:
  sleep ; Go to sleep
  rjmp loop
;
; End of source code                

15MHz-Quarz macht 100 Hz Das ist ein Standardlauf mit der beschriebenen Software.


©2019 by http://www.avr-asm-tutorial.net