4
\$\begingroup\$

I had an error in the configuration of PWM for the atmega8 because I didn't set my register properly. But I thought that Timer 1 is timer 1, no matter is TCCR1A or TCCR1B. Why can I set all the timer 1 using only TCCR1A like so:

TCCR1A  = ((1 << COM1A1) | (1 << COM1A0) (1 << CS11) | (1 << WGM13) );

Datasheet

EDIT : I was confused about the fact that TCCR1A and TCCR1B are different registers which are set for the same timer.

\$\endgroup\$

closed as unclear what you're asking by Olin Lathrop, Daniel Grillo, Chetan Bhargava, Matt Young, Stephen Collings Dec 2 '13 at 18:43

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ Your questions is unclear to me. Please write more detailed and explain better. Also the specific atmega chip and a link to the datasheet is always a good thing to add to the question. \$\endgroup\$ – iQt Dec 1 '13 at 14:54
  • \$\begingroup\$ I did my best to explain it above. Basically, why I cannot do PWM like this : TCCR1A = ((1 << COM1A1) | (1 << COM1A0) (1 << CS11) | (1 << WGM13) ); \$\endgroup\$ – Napster Dec 1 '13 at 14:59
6
\$\begingroup\$

First of all I think you missed a | symbol:

TCCR1A  = ((1 << COM1A1) | (1 << COM1A0) (1 << CS11) | (1 << WGM13) );

TCCR1A  = ((1 << COM1A1) | (1 << COM1A0) | (1 << CS11) | (1 << WGM13) );

Second:

  • Bits COM1A1 and COM1A0 are in register TCCR1A
  • Bits CS11 and WGM13 are in TCCR1B

TCCR1A and TCCR1B are different registers, but they work on the same timer, timer1. They configure different behavior and are located in separate registers, simply because all the bits don't fit in a single byte.

Notice that COM1A1 is simply an alias for the number 7, so is COM1A0 alias for number 6, WGM13 is an alias for number 4 and CS11 for 1. It is up to you, the user, to check if you are writing the correct bits in the correct registers. The compiler does not check this for you.

For example the following three lines will have the same resulting assembly code:

TCCR1A = ( 1 << COM1A1 );
TCCR1A = ( 1 << PB7 );
TCCR1A = ( 1 << ICNC1 );

All three lines will result in the following identical two assembly instructions:

ldi r24, 0x80
out 0x2F, r24

TCCR1(A|B) cannot be accessed as a single 16 bit register like TCNT1(H|L) can.

\$\endgroup\$
  • 1
    \$\begingroup\$ Wow,thanks, this was the answer I was looking for. \$\endgroup\$ – Napster Dec 1 '13 at 16:34
1
\$\begingroup\$

I think you are missing setting the PWM output pin Data Direction Register to output (DDRx) and a value have to be set in the ICR1.

From the data sheet about DDR:

"If one or both of the COM1B1:0 bit are written to one, the OC1B output overrides the normal port functionality of the I/O pin it is connected to. However, note that the Data Direction Register (DDR) bit corresponding to the OC1A or OC1B pin must be set in order to enable the output driver."

So you have to set the DDR when though setting the COM1A1 and COM1A0 bits.

From the data sheet about counting:

"In phase and frequency correct PWM mode the counter is incremented until the counter value matches the value in ICR1 (WGM13:0 = 8)"

This means that ICR1 register in your case will be the value you have to adjust since you set WGM13 only:

ICR1 WGM13

\$\endgroup\$

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