ATtiny85 Fast PWM Mode 7

Hi,

General question regarding how Fast PWM works on Timer0 using mode 7 (WGM02 = 1, WGM01 = 1, WGM01 = 1)

From the data sheet it seems like you can still get PWM output on OC0A and OC0B and that you set OCRA as TOP.

When using the following code I have noticed that PB0 stays high constantly - no matter what I set in OCR0A.

#include <avr/io.h>

int main(void)
{
  DDRB |= 1 << PB0 | 1 << PB1;
  TCCR0A = 1 << COM0A1 | 0 << COM0A0 | 1 << COM0B1 | 0 << COM0B0 | 1 << WGM01 | 1 << WGM00;
  TCCR0B = 1 << WGM02 | 1 << CS00;
  OCR0A = 16;
}

I saw some other code that used Fast PWM mode 7 in this way:

#include <avr/io.h>

int main(void)
{
  DDRB |= 1 << PB0 | 1 << PB1;
  TCCR0A = 1 << COM0A1 | 0 << COM0A0 | 1 << COM0B1 | 0 << COM0B0 | 1 << WGM01 | 1 << WGM00;
  TCCR0B = 1 << WGM02 | 1 << CS00;
  OCR0A = 16;
  OCR0B = 8;
}

With this code you can change top by adjusting OCR0A and then adjusting the duty cycle using OCR0B giving you control over pwm frequency and duty cycle.

My questions are:

  • Is this the way Fast PWM Mode 7 is meant to work on Timer0?
  • Are we only able to get a PWM signal out of PB1?
  • Is PB0 PWM output disabled in FAST PWM Mode 7?

Thanks

Maybe this site is useful for you
Programming Arduino Timer 0 in Fast PWM mode | ee-diary

You need to read the data sheet very carefully. For example

When OCR1A or OCR1B contain $00 or the top value, as specified in OCR1C register, the output PB1(OC1A) or
PB4(OC1B) is held low or high according to the settings of COM1A1/COM1A0. This is shown in Table 12-2.

It should be obvious that if you want to use an OCR register to set TOP (the period), it can't also be used as a compare register to set the PWM percentage. Choose another mode.

http://w8bh.net/avr/TrinketTimers.pdf

Thanks @Kai-R @ZX80. The information you provided seems to confirm what I was experiencing.

To sum up it up - this is how I understand Timer0 PWM mode 7 to work on the ATtiny85:

  1. In Fast PWM mode 7 OC0A will only ever output a PWM signal when the Reserved compare output mode is selected (row 2 in the table below). No other compare output modes will produce any PWM output on OC0A (in Fast PWM mode 7). This compare output mode produces a PWM signal with a fixed duty cycle of 50% at variable frequency. The frequency can be adjusted by setting OCR0A which acts as the counter TOP. The output for this PWM signal will be OC0A.

  2. OC0B is able to output a PWM signal in non-inverting or inverting compare output mode (in Fast PWM mode 7). This requires the use of registers OCR0A and OCR0B. OCR0A acts as the TOP for the counter and OCR0B is the value at which a compare match is made. This allows for adjustment of PWM frequency and duty cycle. The output for this PWM signal will be OC0B.

The datasheet doesn't seem to document Fast PWM mode 7 clearly enough. From the documentation it seems like OC0A should also be able to work in non-inverting or inverting compare output mode (row 3 - 4 in the table above) but it does not. It only works in the Reserved compare output mode (row 2 in the table above). For other compare output modes in PWM mode 7 you have to use OC0B as the output of your PWM signal.

1 Like

Just out of curiosity, does your program require delay functions or millis()? Changing timer 0 on the ATmega328p and ATmega2560 can cause the specified functions to not work properly.

Hi,

No it doesn't - this was just to confirm how the different PWM modes work on the attiny85 :slight_smile:

As you've mentioned - using timer0 in certain modes will cause functions that depend on it such as mills ECT to break.

I've actually made a program to investigate five of the PWM modes. In the virtual oscilloscope attached below, the OCRXX register is set to 78.4% duty cycle From what I've found, analogWrite() is equivalent to 8-bit phase correct PWM with clock divisor 64.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.