ATtiny85, timer 1B does not work if COM1A1|COM1A0==0

16 posts / 0 new
Last post
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,
I read the datasheet,and checked

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=133861&highlight=com1a1+timer+b

but I cannot understand why on an attiny85

int main(){
    TCCR1|=_BV(CS10);
    GTCCR|=_BV(PWM1B);
    GTCCR|=_BV(COM1B1)|_BV(COM1B0);    
    DDRB|=_BV(PB4);  
    OCR1B=0x80;
    while(1){}
  }

does not work until I add

    TCCR1|=_BV(COM1A0);

which I guess I should not need if I want to use only timer 1B

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IIRC this has come up before, but I can't find the thread. Perhaps this one?
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=119678&highlight=errata+pwm
or this?
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=88033&highlight=errata+pwm

In any case, there was an errata on very similar behaviour on some revisions of Tiny45. No mention on the '85, but check the errata list to see if it matches your symptoms.

You can put lipstick on a pig, but it is still a pig.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe this thread, with a test program for that bug.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
In any case, there was an errata on very similar behaviour on some revisions of Tiny45. No mention on the '85, but check the errata list to see if it matches your symptoms.
It's possible. The errata mentioned in the datasheet bears at least a resemblance to the OP's problem. However it is not listed among the errata for the ATtiny85, even in the latest revision of the datasheet. I also can't find anything about this in the errata sticky.

Your code does have some problems I think:

    GTCCR|=_BV(PWM1B);

This mode uses OCR1C as TOP, but you haven't changed it from it's power-on default value of 0x00. TCNT1 will never change from 0x00, but it will cause a compare match to occur on every timer tick.

This:

    GTCCR|=_BV(COM1B1)|_BV(COM1B0);    

... correctly sets inverting mode for OC1B, but with:

    OCR1B=0x80;

... a compare match will occur when TCNT1 reaches 0x80, but since OCR1C = 0x00 that will never happen.

Strictly speaking, since you set a prescaler of 1 with:

    TCCR1|=_BV(CS10);

... before configuring GTCCR, TCNT1 will have counted a couple of ticks by the time you set PWM1B, so TCNT1 will have missed it's first match with the default OCR1B and will count all the way to 0xFF, but only once. On it's way, there will be a compare match with OCR1B and OC1B will be set, but thereafter TCNT1 will be locked at 0x00, and OC1B will be cleared and stay cleared.

snigelen wrote:
Maybe this thread, with a test program for that bug.
If this elicits the 'short flash' behaviour, then the OP has found a new errata.

This statement:

Quote:
does not work until I add
    TCCR1|=_BV(COM1A0);

... does not reflect the known errata, and even the known errata does not apply to the '85, but it is strange.

Perhaps you can describe exactly what you see. Put a scope on OC1B. What do you see after each instruction in your program? Use _delay_ms(5000) between each line to give you time to see the effect of each:

#define F_CPU 
#include 

int main() {
  _delay_ms(5000);
	TCCR1|=_BV(CS10);
  _delay_ms(5000);
	GTCCR|=_BV(PWM1B);
  _delay_ms(5000);
	GTCCR|=_BV(COM1B1)|_BV(COM1B0);
  _delay_ms(5000);
	DDRB|=_BV(PB4);
  _delay_ms(5000);
  TCCR1|=_BV(COM1A0);
  _delay_ms(5000);
	OCR1B=0x80;
	while(1){}
}

After examining OC1B, try again examining OC1A for the sake of completeness.

Don't forget to correctly define F_CPU before the #include

JJ

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience. Experience comes from bad judgement."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

it is not listed among the errata for the ATtiny85,

Follow sniggie's link above--he found it on some '85s.

Quote:

This mode uses OCR1C as TOP, but you haven't changed it from it's power-on default value of 0x00.

That timer is a "strange beast" for us AVR8 users. As I read the datasheet, there is a 0x00 mode an an OC1C mode, kind of. But you could well be right. I've got simple PWMs for this family in a couple apps but I don't think I've ever fully explored these corners.

You can put lipstick on a pig, but it is still a pig.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:
it is not listed among the errata for the ATtiny85,
Follow sniggie's link above--he found it on some '85s.
So he has. I just imagined that even the first released '85 post-dates the erratum altogether, and that the latest datasheet from atmel would acknowlege the discovery of this erratum in the '85. Perhaps I'm giving them too much credit ;)

In any case, unless the OP has left something out, what he's describing doesn't quite match this particular erratum. Perhaps it's something new?

Quote:
Quote:
This mode uses OCR1C as TOP, but you haven't changed it from it's power-on default value of 0x00.
That timer is a "strange beast" for us AVR8 users. As I read the datasheet, there is a 0x00 mode an an OC1C mode, kind of. But you could well be right. I've got simple PWMs for this family in a couple apps but I don't think I've ever fully explored these corners.
In fairness, neither have I. I was just going by the datasheet:
Quote:
• Bit 6 – PWM1B: Pulse Width Modulator B Enable
    When set (one) this bit enables PWM mode based on comparator OCR1B in Timer/Counter1 and the counter value is reset to $00 in the CPU clock cycle after a compare match with OCR1C register value.
I did spot an error in my analysis. Since PWM1B is set first, the change to OCR1B won't be latched until TCNT1 does it's once-only overflow back to 0x00 = OCR1C, so OC1B will never be set.

JJ

P.S. Why am I being captcha'd when there are no links in this post? (again :x)

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience. Experience comes from bad judgement."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

P.S. Why am I being captcha'd when there are no links in this post? (again

Ummm--have you looked in the mirror lately? :twisted: "Profiling" at its best...

You can put lipstick on a pig, but it is still a pig.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:
P.S. Why am I being captcha'd when there are no links in this post? (again
Ummm--have you looked in the mirror lately? :twisted: "Profiling" at its best...
That's rich, coming from the poster child for BSE ;)

Actually, I have somewhat more hair than my avatar suggests...

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience. Experience comes from bad judgement."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Actually, I have somewhat more hair than my avatar suggests...

Not for long!

Torby

 

Cartesian coordinates are SO 17th century.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Torby wrote:
Quote:
Actually, I have somewhat more hair than my avatar suggests...
Not for long!
The bow tie is meant to distract...

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience. Experience comes from bad judgement."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you to all you guys.
I changed the code to

OCR1C=0xFF;
  GTCCR|=_BV(PWM1B); 
  TCCR1|=_BV(COM1A0);
  GTCCR|=_BV(COM1B1)|_BV(COM1B0);    
  TCCR1|=_BV(CS10); 
  DDRB|=_BV(PB4)|_BV(PB3)|_BV(PB0)|_BV(PB1);  
  OCR1A=0x1; 
  OCR1B=0x40; 

and I can confirm that the config
_BV(COM1A1)|_BV(COM1A0)==0
GTCCR|=_BV(COM1B1)|_BV(COM1B0);
is the only configuration that does not work as expected.
I checked whether the problem is the same of the attiny45, i.e. that the two configs should be the same, but that is not the case.
b.t.w, it is an attiny85v, it says 101S attiny85v 10PU

Pages