ATTiny85 PWM from Timer/Counter1


I’ve been tinkering with the ATTiny chip a bit lately, and I wanted to hook up of my stepper motors to it. This chip has 2 timers, and a few pins that can output PWM signals.

I had OC1B on PB4/pin3 free, and the Timer/Counter1 module looked a bit better than the Timer/Counter0 module for the relatively-long pulse needed to control the stepper motor.

First thing to figure out is what I wanted the PWM signal to look like. Stepper motors care more about the pulse length than the frequency. My motor accepted 700-1500us as the control range, so I decided to go with a 4000us period (250Hz).

The way that the Timer/Counter1 module works is it will increase its count from 0 to a certain register value (OCR1C), and then reset to zero. In PWM mode, the OC1B pin is cleared when the counter hits a certain value (OCR1B), and set when the counter is 0. So, if you control OCR1C, you can control the the period, and by controlling OCR1B, you can control the pulse width. I decided to use the full width of the counting (8 bits), so OCR1C would be set to 0xFF.

Next I had to figure out how quickly the counter would be incrementing. This is selected via the system clock rate, and the prescaler on the timer. I needed the 16Mhz PLL clock on the chip (CLKSEL=0x0001), so that was fit. I selected 256 as the prescaler value so that:

16Mhz / 256 (prescalar) / 256 (OCR1C) = ~4ms.

Time to write some code!

//fuses: L: 0xE1 H: 0xDD E: 0xff
#define F_CPU 16500000
#include <avr/io.h>
#include <util/delay.h>
void main()
    //Set Pin3/PB4 to output
    DDRB = 1 << DDB4;
    //approximately a 700us pulse
    OCR1B = 0x2D;
    OCR1C = 0xFF;

    TCCR1 = 1 << CTC1 | //clear on match with OCR1C
            9 << CS10;  //set prescaling to clk/256
    GTCCR = 1 << PWM1B | //enable PWM mode on OC1B
            2 << COM1B0; //clear OC1B when we hit OCR1B
    for (;;)


Now that that was written, hooked up a simple circuit, and hooked my logic analyzer to a resistor on the output pin to verify the output:


The logic analyzer showed:


Success! A 4ms period with a 700us pulse width. I could now drive my stepper motor, and by changing OCR1B, I could designate which position the motor was in.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.