4
\$\begingroup\$

I want to enable high-speed PWM output on PB4 using an ATtiny85. Having read the datasheet, it appears that the following conditions need to be met:

  • PLL and PCK need to be set to enable the high-speed peripheral clock
  • The prescaler needs to be set to enable timing
  • OCR1B and OCR1C need to be set to choose duty cycle
  • PB4 needs to be configured as an output and the compare mode needs to be set using COM1B0/COM1B1
  • PWM B needs to be enabled using GTCCR:PWM1B

The code below works - I see PWM output on PB4 and can vary the duty cycle by changing OCR1B - however it only works if I also set COM1A0 in TCCR1. If I don't set COM1A0 then PB4 stays high and no PWM output is generated.

#include <avr/io.h>
#include <avr/delay.h>

int main() {
// Enable PLL and async PCK for high-speed PWM
PLLCSR |= (1 << PLLE) | (1 << PCKE);

// Set prescaler to PCK/2048
TCCR1 |= (1 << CS10) | (1 << CS11) | (0 << CS12) | (0 << CS13);

// Set OCR1B compare value and OCR1C TOP value
OCR1B = 128;
OCR1C = 255;

// Enable OCRB output on PB4, configure compare mode and enable PWM B
DDRB |= (1 << PB4);
GTCCR |= (1 << COM1B0) | (1 << COM1B1);
GTCCR |= (1 << PWM1B);

// Why is this necessary?
TCCR1 |= (1 << COM1A0);

while (1) {}

return 0;
}

Why is this necessary? The datasheet states that the COM1A bits control OC1A/PB1, which shouldn't have anything to do with OC1B and OCRB

The reason I'm trying to use OC1B/PB4 rather than OC1A/PB1 is that PB4 is not used during ISP while PB1 is

\$\endgroup\$
5
\$\begingroup\$

Is this an old chip? It appears a couple people have also had this problem.

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=119678

Towards the bottom of the thread they concluded it was a hardware issue in the chip that has since presumably been fixed. Your code looks good. I wonder if Atmel ever fixed the issue.

The ATtiny85 datasheet in the Errata (section 27.2.3 / page 213) says:

4) Timer Counter 1 PWM output generation on OC1B – XOC1B does not work correctly
Timer Counter1 PWM output OC1B-XOC1B does not work correctly. Only in the case when the control bits, COM1B1 and COM1B0 are in the same mode as COM1A1 and COM1A0, respectively, the OC1B-XOC1B output works correctly.

Problem Fix/Work around
The only workaround is to use same control setting on COM1A[1:0] and COM1B[1:0] control bits, see table 14- 4 in the data sheet. The problem has been fixed for Tiny45 rev D.

\$\endgroup\$
2
\$\begingroup\$

This really stumped me for a while. I've been reading with the data sheet and for the most part, everything you said is correct to me. However, I noticed some potential discrepancies so I'm going to fire these at you and maybe we'll find out what the problem is.

First of all, I checked the TCCR1 register and looked at the COM1A0 bit:

enter image description here

It is true that by the table, this clearly states that the COM1A[1:0] bits regard only the OC1A PWM output. Note that at the bottom, it says:

"In PWM mode, these bits have different functions"

So I checked out table 12-1.

enter image description here

The table shows COM1x1 and COM1x0 manipulate the OC1x pin. One would intuitively think that if one is changing the COM1A[1:0], then it would only manipulate the OC1A PWM pin. However, see the text above:

"When the counter value match the contents of OCR1A or OCR1B, the OC1A and OC1B outputs are set or cleared"

This seems to suggest that if OCR1A OR OCR1B is matched, the OC1A AND OC1B outputs are set, or cleared, according to the COM1x[1:0] bits.

So it seems to me that manipulating the COM1x[1:0] bits, provided that the HW is enabled in PWM mode, that these PWM outputs are both influenced at the same time. This is why when you have COM1A[1:0] cleared to '00', table 12-1 says that the PWM outputs are not connected.

Just a thought, perhaps someone more enlightened can critique my logic.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.