You must write the clock-select bits to the correct value. The simplest
way to do it is to write the proper configuration into the TCCR1B
register:
TCCR1B = (1<<CS12)|(1<<CS10);
In your program, you used |=
instead of =
. This doesn't write the
bits appropriately: it only sets (writes to 1) the bits CS12
and
CS10
but doesn't clear CS11
. Since the Arduino core library sets the
prescaler to 64 (CS11
and CS10
set), you end up with all the
clock-select bits sets, in which case the timer is clocked by an
external signal on the T1 pin. Not what you want.
Edit: Judging from the comments, it appears that at least dannyf did not understand my answer, I am therefore adding a clarification. There are two scenarios when you may want to tweak the control registers of a peripheral:
The peripheral is normally controlled by the Arduino core library, and you want to use it through that library. Typical case: you want to use a timer to
analogWrite()
, or the ADC toanalogRead()
, but you want to clock the peripheral at a frequency which is not the core's default.You want to use a peripheral directly rather than through the Arduino core. Either you are going to "take it over" from the core, or it's a peripheral the core doesn't use in the first place.
In the first case, you should only touch those bits of the control registers that you must change. The other bits should be left alone, at whatever values the core has set them to. This is the approach of dannyf's answer.
In the second case, it is wiser to not rely on the core's default setting, and instead write every single bit of the control registers to the values appropriate for your application. This is the scenario of the original question, and the solution proposed in my answer.
For the particular case of this question, the TCCR1B
register would
be set to: ICNC1 = 0†, ICES1 = 0, reserved bit = 0, WGM13
= 0, WGM12 = 0, CS12 = 1, CS11 = 0 and CS10 = 1. Combining those bits
together gives the setting TCCR1B = 0x05;
. However, for readability
reasons, I prefer to write that value (1<<CS12)|(1<<CS10)
, as in the
question and in my original answer. Some people may prefer to explicitly
write every bit, like
TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<5) | (0<<WGM13)
| (0<<WGM12) | (1<<CS12) | (0<<CS11) | (1<<CS10);
Whichever version you prefer is up to you. I personally don't find this latter version any easier to read.
†: The values of ICNC1
and ICES1
are actually
irrelevant in this case.
You must write the clock-select bits to the correct value. The simplest
way to do it is to write the proper configuration into the TCCR1B
register:
TCCR1B = (1<<CS12)|(1<<CS10);
In your program, you used |=
instead of =
. This doesn't write the
bits appropriately: it only sets (writes to 1) the bits CS12
and
CS10
but doesn't clear CS11
. Since the Arduino core library sets the
prescaler to 64 (CS11
and CS10
set), you end up with all the
clock-select bits sets, in which case the timer is clocked by an
external signal on the T1 pin. Not what you want.
You must write the clock-select bits to the correct value. The simplest
way to do it is to write the proper configuration into the TCCR1B
register:
TCCR1B = (1<<CS12)|(1<<CS10);
In your program, you used |=
instead of =
. This doesn't write the
bits appropriately: it only sets (writes to 1) the bits CS12
and
CS10
but doesn't clear CS11
. Since the Arduino core library sets the
prescaler to 64 (CS11
and CS10
set), you end up with all the
clock-select bits sets, in which case the timer is clocked by an
external signal on the T1 pin. Not what you want.
Edit: Judging from the comments, it appears that at least dannyf did not understand my answer, I am therefore adding a clarification. There are two scenarios when you may want to tweak the control registers of a peripheral:
The peripheral is normally controlled by the Arduino core library, and you want to use it through that library. Typical case: you want to use a timer to
analogWrite()
, or the ADC toanalogRead()
, but you want to clock the peripheral at a frequency which is not the core's default.You want to use a peripheral directly rather than through the Arduino core. Either you are going to "take it over" from the core, or it's a peripheral the core doesn't use in the first place.
In the first case, you should only touch those bits of the control registers that you must change. The other bits should be left alone, at whatever values the core has set them to. This is the approach of dannyf's answer.
In the second case, it is wiser to not rely on the core's default setting, and instead write every single bit of the control registers to the values appropriate for your application. This is the scenario of the original question, and the solution proposed in my answer.
For the particular case of this question, the TCCR1B
register would
be set to: ICNC1 = 0†, ICES1 = 0, reserved bit = 0, WGM13
= 0, WGM12 = 0, CS12 = 1, CS11 = 0 and CS10 = 1. Combining those bits
together gives the setting TCCR1B = 0x05;
. However, for readability
reasons, I prefer to write that value (1<<CS12)|(1<<CS10)
, as in the
question and in my original answer. Some people may prefer to explicitly
write every bit, like
TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<5) | (0<<WGM13)
| (0<<WGM12) | (1<<CS12) | (0<<CS11) | (1<<CS10);
Whichever version you prefer is up to you. I personally don't find this latter version any easier to read.
†: The values of ICNC1
and ICES1
are actually
irrelevant in this case.
You must write the clock-select bits to the correct value. The simplest
way to do it is to write the proper configuration into the TCCR1B
register:
TCCR1B = (1<<CS12)|(1<<CS10);
In your program, you used |=
instead of =
. This doesn't write the
bits appropriately: it only sets (writes to 1) the bits CS12
and
CS10
but doesn't clear CS11
. Since the Arduino core library sets the
prescaler to 64 (CS11
and CS10
set), you end up with all the
clock-select bits sets, in which case the timer is clocked by an
external signal on the T1 pin. Not what you want.