Find file History

README.md

#255 AvrHardwarePWM/ATtiny

All about hardware PWM with the ATtiny85.

Build

▶️ return to the LEAP Catalog

Notes

See the AvrHardwarePWM project for all about hardware PWM with the Arduino UNO/ATmega328.

This project takes the same background and exercises hardware PWM with an ATtiny85 processor.

ATtiny Timers

There are two timers in the ATtiny85 that can be used to generate PWM signals:

  • Timer 0 is an 8-bit timer. capable of phase correct and Fast PWM (similar to the ATmega). It is used for functions such as delay() and millis() - these will be affected if PWM frequency is changed.
  • Timer 1 is an 8-bit timer, capable of two Fast PWM outputs. It acts as an up-counter, with TOP defined by OCR1C. It also with complementary outputs.
Compare Register Timer output Chip pin Pin name
OCR0A OC0A 5 PB0
OCR0B OC0B 6 PB1
OCR1A OC1A 6 PB1
OCR1B OC1B 3 PB4
OCR1A OC1A, complementary output 5 PB0
OCR1B OC1B, complementary output 2 PB3

NB:

  • the chip pin references are for the PDIP/SOIC/TSSOP package.

Summary of the Timer-related registers:

TCCR_summary

How Fast is the Clock?

The ATtiny85 can use an external clock, but by default it uses an internal oscillator. The internal oscillator runs at 8 MHz, prescaled to 1 MHz by default.

The clock settings are in the fuses. I used avrdude to read the fuses:

$ avrdude -c stk500v1 -p attiny85 -P /dev/cu.usbmodem14521 -b 19200 -U lfuse:r:-:i

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.05s

avrdude: Device signature = 0x1e930b (probably t85)
avrdude: reading lfuse memory:

Reading | ################################################## | 100% 0.02s

avrdude: writing output file "<stdout>"
:01000000629D
:00000001FF

avrdude: safemode: Fuses OK (E:FF, H:DF, L:62)

avrdude done.  Thank you.

The engbedded fusecalc site is invaluable for decoding or calculating fuses values.

It confirms that E:FF, H:DF, L:62 are factory defaults: 8 MHz internal oscillator with CKDIV8 prescaler: so it is running at 1 MHz.

Example Sketch

ATtiny.ino exercises the PWM modes, primarily so they can be captured with an oscilloscope. The push-button attached to pin 7 is used to cycle through a few demonstration modes.

The demonstration modes are not exhaustive, but show off most of the PWM capabilities.

I'm using consistent scope connections in all examples:

Timer output Chip pin Pin name Scope Channel
OC0A 5 PB0 2 (blue)
OC0B 6 PB1 1 (yellow)
OC1A 6 PB1 1 (yellow)
OC1B 3 PB4 3 (red)
OC1A, complementary output 5 PB0 2 (blue)
OC1B, complementary output 2 PB3 4 (green)

demoTimer0a: Timer0 Fast PWM

  • Fast PWM, TOP=0xFF (WGM01, WGM00)
  • Prescaler: 1 (CS00), frequency = 3.906 kHz, Measured: 3.935 kHz
  • Outputs:

mode_0a

demoTimer0b: Timer0 Phase Correct PWM

  • Phase Correct PWM, TOP=0xFF (WGM00)
  • Prescaler: 1 (CS00), frequency = 1.961 kHz, Measured: 1.984 kHz
  • Outputs:
    • PB0 duty cycle = 127/256 = 49.6%
    • PB1 duty cycle = 191/256 = 74.6%
    • no output on PB3, PB4 (except some crosstalk/noise)
    • not the phase correction between the two outputs; start/end of each period is at the top/bottom of the count

mode_0b

demoTimer0c: Timer0 Fast PWM, alternative prescaler

  • Fast PWM, TOP=0xFF (WGM01, WGM00)
  • Prescaler: 64 (CS01, CS00), frequency = 61 Hz, Measured: 61 Hz
  • Outputs:

mode_0c

demoTimer1a: Timer1 dual Fast PWM, reduced resolution

  • Fast PWM, TOP=0xFF (WGM01, WGM00)
  • Prescaler: PCK (CS10), frequency = 7.874 kHz, Measured: 7.905 kHz
  • 4-bit counter: OCR1C = 127
  • Outputs:

mode_1a

demoTimer1b: Timer1 dual Fast PWM, complementary outputs

  • Fast PWM, TOP=0xFF (WGM01, WGM00)
  • Prescaler: PCK (CS10), frequency = 3.906 Hz, Measured: 3.953 kHz
  • 8-bit counter: OCR1C = 255
  • Complementary outputs enabled (COM1A0, COM1B0)
  • Outputs:

mode_1b

Construction

Breadboard

Schematic

ATtiny_breadboard

Credits and References