Path: Home => AVR overview => Applications => ATtiny with crystals   Diese Seite in Deutsch: Flag DE Logo
Tiny XTAL oscillator Applications of
AVR single chip controllers AT90S, ATtiny, ATmega and ATxmega
To clock an ATtiny with a crystal

ATtiny with a crystal

A simple task: an ATtiny is to be clocked with an external crystal instead of using the inaccurate internal RC oscillaor as clock source. And: from that clock source an accurate rectangle with a desired frequency shall be generated. A simple task, but there are many hurdles and things you can do wrong or that do not work as desired. Here are some hints how to do that.

CMOS version of the crystal divider And that would be such a crystal divider without a microcontroller. Designed to divide a crystal of 15 MHz by 68: In total three 14 pin ICs are necessary and 42 pins have to be handled.

The ATtiny25 microcontroller version, doing exactly the same, fits into one single 8-pin IC, of which only six have to be handled. The whole design is inside the controller, which is brought to perform all that by a few lines of assembler code.

1 An xtal controlled rectangle generator

You need to have an accurate rectangle swing? Simple, just do that:
  1. To clock an ATtiny with an external crystal.
  2. Use an internal timer/counter in CTC mode (Clear Timer on Compare) and divide the clock by an integer value.
  3. Write this divider, minus 1, to the compare register(s) of the timer, with an 8 bit timer to Compare A, with a 16 bit timer either to compare A or to the ICR (Input Capture Register).
  4. Configure the output pins OCnA and/or OCnB to toggle on Compare Matches.
  5. Configure the output pins OCnA and/or OCnB as outputs by setting their data direction bits.
  6. Start the timer by writing the prescaler bits to TCCR0B.
Nothing else has to be done, no interrupts or any additional code to be executed, so set the controller to sleep or run into an indefinite loop. The timer/counter takes over the control and generates a nice and accurate rectangle swing.

From one single crystal diverse frequencies can be derived in that way. And very flexible: just change the divider. With the OpenOffice spreadsheet here all different crystals available commercially can be examined: Cells with "-" mark impossible combinations.

If cell E6 resp. J6 is 0.00, then the exact desired frequency can be generated with at least one crystal. Which one(s) that are (and the one with the smallest difference, if none is exactly zero) can be seen from the green colored differences in columns E resp. J. Crystals with less than 0.1% difference to the desired frequency are displayed with a yellow background.

Ensure that you subtract one from the CTC divider value before writing that to the compare register of the timer/counter.

2 The hardware

Schematic of the crystal oscillator/divider This is the complete hardware. The two ceramic capacitors of 18 pF are in any case necessary to ensure that the crystal swings.

The output signal is available on PB0 (OC0A) and, if so desired and programmed, on PB1 (OC0B). Both outputs can be inversely phased or can be phased to a different angle.

In practice, and with a 15 MHz crystal attached, the crystal did only start below an operating voltage of 4 V. Above that the crystal started for a few clock cycles but then stopped working. This did not change if I divided the XTAL2 output pin voltage by two resistors before feeding the xtal. If the oscillator runs at e.g. 2.7 V, an increase of the operating voltage to above 4 V (up to 5.5 V) did not stop the oscillation. So it is a simple start-up issue. If you use an operating voltage of 5 V, make sure that the ATtiny is at 3.3 V or below, e.g. with a resistor, a Zener diode and an electrolytical capacitor. Or prepare a special solution to ensure that the oscillator swing is stable before increasing the operating voltage.

I did not find any similar reports of that kind of buggy hardware. Fortunately I had a large capacitor attached, so I saw a few of the initial swings. Depending from the number of instructions already executed the portpins OCR0A and OCR0B were either outputs or not. An error like this can drive you crazy, so do not expect hardware to work as planned, desired and as described in the device's databook.

An additional hint for the use of a trim capacitor to alter the crystal's frequency slightly. This works only on the XTAL1 input. Do not expect a large effect, only a few Hz and less than 1 kHz can be reached. Increasing capacitor values lead to increasing frequencies, at least with my 15 MHz crystal. Attention: a too large cap can stop the crystal from swinging.

3 Altering the fuses

By default the ATtiny works with its internal RC oscillator, divided by 8. To enable the external crystal, the fuses have to be changed as follows:
  1. CLKDIV8 have to be switched off, only leave that fuse set if you really want to divide the crystal frequency by 8.
  2. CLKSEL has to be changed to either a Low-Speed external crystal (e.g. with 32.768 kHz) or to an external crystal oscillator. Even though Studio 4.19 does not offer an external crystal it works to set the fuse to an external crystal oscillator even though there only a crystal attached. The menu entries in the Studio 4.19 are confusing, just because they allow only a low-speed crystal.
Special care has to be taken if you use a 32.768 kHz crystal. Prior to this fuse change ensure the following single steps:
  1. Reduce the ISP frequency to below 8 kHz. If your programmer has no such option, give up at that early point.
  2. Disable the CLKDIV8 fuse.
  3. Select the low-speed external crystal option with a long start-up procedure.
An additional issue is that the Studio denies to program flash or EEPROM with ISP frequencies below 5 kHz. As STK500 clones do not offer an ISP frequency between 5 and 8 kHz you'll not be able to program the ATtiny. AVRISP-MKII clones offer 6 kHz, which is fine.

If you forget to clear the CLKDIV8 fuse, your ATtiny will not be accessible any more, because the Studio denies to program flash or EEPROM memory with less than 5 kHz clock. In that case only parallel-HV-programming can be used to revive the chip (which is possible with an STK500).

4 Converting rectangles to sine waves

If you don't need rectangles but a clean sine wave, you'll have to filter those rectangles with a RC filter network.

Single stage RC filter 1 Hz after a 100k/3u3 filter Such RC filters, here a single-stage, damp or suppress higher frequencies. Their amplitude drops steaper the higher the frequency. Here a R=100kΩ and a C=3µF RC filter at work. The first harmonic of the rectangle at 3 Hz is already damped a bit, the result can be seen to the right.

That does not yet look like a sine, but it isn't a rectangle either.

1 Hz after a 2-stage 100k/3u3 filter If we invest a second R and a second C of the same size, we yield a wave form that is already nearer to a sine wave.

1 Hz after a 3-stage 100k/3u3 filter Even more sine wave: a 3-stage RC filter at work. The green curve at the end of the filter looks very close to a sine wave.

Please note that in each stage we loose some amplitude. Here it drops from 0.79 Vpp to 0.32 Vpp, approximately with a factor of 2.

Four-stage RC filter 1 Hz after a 4-stage 100k/3u3 filter This is the same filter with four stages and the voltage on all four capacitors.

1 Hz after a 100k/1u filter If you need a higher amplitude, pick a smaller capacitor or resistor. This here is a capacitor of 1 µF, three times smaller.

RC simulation software starting Those who want to play with the diverse parameters (number of stages, resistors and capacitors, etc.) can do that with my Lazarus-Pascal software, that I compiled for Win64 as executable here (packed). If you need the Lazarus source code, then notify me.

If you start the executable it looks like this.
RC simulation software selection If you choose an RC combination from the two selection fields in the lower left window, this combination is calculated and displayed. The dropdown-selector N allows to decrease and increase the number of RC stages. If you click on the colored buttons, you can select the curve's color. If you select white as color, the curve is calculated but not displayed.

Changing the displayed start time Nearly all parameters can be adjusted. If you click into the entry field, it gets yellow. You can edit the entry. If you want to finish editing, just press the Enter key and the new parameter is applied. If your entry is not correctly understood, the entry field turns red.

The entry fields understand abbreviations for multiples, such as k or K, or M as well as m, u for µ, n or p.

1 Hz zoomed If you adjuste the voltages or the time to be displayed you can zoom into parts of the curve.

If you click onto the picture displayed, you can save the picture as PNG- or BMP-grahics file.

Note that if you select certain small RC combinations for a low frequency entry, the simulation software encounters numeric overflows. Choose some higher R's and/or C's in that case.

5 Software and downloads

The assembler software can be downloaded from here. The listing is documented below.

Additionally the following OpenOffice documents can be downloaded: The source code:

;
; *********************************
; * 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 crystal generates 100 Hz This is a simulation with the above listed software setting.


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