Arduino is an open-source microcontroller platform that is widely used for various applications such as robotics, home automation, and other interactive projects. One of the most important features of the Arduino microcontroller is its timer system, which allows for precise timing and triggering of events. The Timer 1 module of the Arduino is a 16-bit timer that is capable of generating accurate time intervals and triggering events based on those intervals.
Within the Arduino Timer 1 Clear Timer on Compare Match (CTC) mode, there are four modes we can choose which are as follows.
- Normal Mode(OC1A/OC1B disconnected)
- Toggle Mode
- Clear OC1A/OC1B
- Set OC1A/OC1B
In this blog post, it is shown how we can use the Normal mode and the Toggle mode and understand their differences.
Clear Timer on Compare Match (CTC) mode
The CTC mode is a timer mode that generates a time interval based on the comparison of the timer's count value with a specified top value. The top value is set by the user and acts as the limit for the timer's count. When the timer reaches this value, it automatically resets to zero and generates an interrupt. This allows for precise timing and repetition of events.
The CTC mode can be useful in applications where a precise interval needs to be maintained. For example, in robotics, you may want to control the speed of a motor by setting a precise time interval for each step. In such a scenario, the CTC mode can be used to generate the required interval and trigger events based on that interval.
Normal mode
In normal mode, the count or compare value is loaded into one of the OCR1A or OCR1B register. The counting is started and the when the count value is reached, the counter resets and starts counting again. When the count value is reached the compare overflow flag is set and we can use monitor this flag and do desired task when the compare value is reached. Also we can enable the compare interrupt and perform task in the ISR routine of the compare match.
In normal mode, the OC1A and OC1B pins which are the pin 9 and 10 pins on Arduino Uno(and similar boards) are disabled from generating CTC signal. So we can use these pins like any other pins.
For example, lets say that we want to set the count value such that when the time period is 1/f=1/500Hz=0.5ms then we want to turn on and off a LED. LED is just an example we could also have used other actuators like motor for example. In this case, we can poll the overflow flag and when the compare value is reached after 0.5ms then we can turn on a LED and after another 0.5ms turn off a LED. The LED can be connected to any Arduino pins, even to the OC1A(pin 9) and OC1B(pin 10).
A sample program code based on polling method for using CTC normal mode wherein a LED connected to pin 7(PD7) is turned on and off at frequency of 500Hz using polling(monitoring overflow flag) is below.
#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif
#define FREQ 500UL // 500Hz
void setup() {
pinMode(7,OUTPUT);
}
void loop(){
// Set up Timer1 in CTC mode
TCCR1A = 0; // Normal port operation, OC1A/OC1B disconnected
TCCR1B = (1 << WGM12) | (1 << CS10); // CTC mode, no prescaler
OCR1A = (F_CPU / 2 / FREQ) - 1; // Compare match value
TCNT1 = 0; // Initialize timer value
while (1)
{
// Check for Timer1 compare match
if (TIFR1 & (1 << OCF1A))
{
// Clear compare match flag
TIFR1 = (1 << OCF1A);
// Toggle output pin
PORTD ^= (1 << PD7);
}
}
}
The same version of the above program that utilizes the compare match interrupt is below.
#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif
#define FREQ 500UL // 500Hz
void setup() {
pinMode(7,OUTPUT);
timer1Config();
}
void loop() {
}
void timer1Config(){
// Set up Timer1 in CTC mode
TCCR1A = 0; // Normal port operation, OC1A/OC1B disconnected
TCCR1B = (1 << WGM12) | (1 << CS10); // CTC mode, no prescaler
OCR1A = (F_CPU / 2 / FREQ) - 1; // Compare match value
TCNT1 = 0; // Initialize timer value
TIMSK1 |= (1<<OCIE1A); // Enable timer compare interrupt
sei(); // Enable global interrupt
}
// Timer 1 compare match interrupt service routine
ISR(TIMER1_COMPA_vect){
PORTD ^= (1<<PD7); // Toggle PB1 to generate wave
}
Note that in the above code we can use any other pins even the Timer 1 pins.
Toggle mode
The CTC toggle mode is another mode of operation for Timer 1 in the Arduino. In this mode, the timer generates an interrupt whenever the timer value reaches the specified top value. However, instead of resetting the timer to zero, it simply toggles a specified output pin(either OC1A or OC1B).
The toggle mode is useful in applications where a continuous sequence of events needs to be generated. For example, in a lighting project, you may want to turn a light on and off repeatedly. In such a scenario, the toggle mode can be used to generate a repeating pattern of on and off states. It can be used for example in building Arduino Variable Frequency Generator.
For in case of toggle mode, we have to use the OC1A(pin 9) or OC1B(pin 10) or both. Also we don't need to monitor the overflow flag.Here is a sample code for Timer 1 CTC toggle mode that blinks a LED connected to pin 10(OC1B pin) at a frequency of 500Hz.#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif
#define FREQ 500UL // 500Hz
void setup() {
pinMode(9,OUTPUT);
// Set up Timer1 in CTC mode
TCCR1A = (1<<COM1A0); // Toggle mode on OC1A
TCCR1B = (1 << WGM12) | (1 << CS10); // CTC mode, no prescaler
OCR1A = (F_CPU / 2 / FREQ) - 1; // Compare match value
}
void loop(){
}
The toggle mode circuit diagram for the above case is shown below.
In conclusion, both the CTC Normal mode and Toggle mode in the Arduino timer 1 have their specific use cases, and the choice between the two depends on the requirements of the project. The CTC Normal mode is ideal for generating precise timing events, while the Toggle mode is ideal for generating square waves. Understanding these modes and how to implement them will help you take full advantage of the Arduino platform's capabilities.
References: