/*
=== TIMER1 ===
1. Normal Mode
2. ** CTC Mode **
3. Fast PWM
4. Phase Correct PWM
5. Phase and Frequency Correct PWM
6. Using the Input Capture Pin
7. External clock
Timer/Counter1 Register TCNT1:
- TCNT1 is 16 bits. Counts corresponding to the system clock, can be slowed down with a prescaler.
Output Compare Registers OCR1A and OCR1B:
- Can define values that are compared with the TCNT1 register. (Compare Match) triggers certain actions.
Timer/Counter1 Control Registers TCCR1A, TCCR1B:
- Choice of Wave Form Generation Mode via the WGM13, WGM12, WGM11, WGM10 Bits
- Determination of what happens in case of a Compare Match COM1A0, COM1B0, COM1A1, COM1B1 Bits
- Prescaler or external clock via the Chip Select Bits CS12, CS11, CS10
Input Capture Register ICR1
- If there is an event on ICP1, the counter reading of TCNT1 is written to ICR1.
- ICES1 bit in register TCCR1B, (ICES1 = 1) rising edge, or (ICES1 = 0) falling edge.
- Like OCR1A, ICR1 is the Top value in some WGM1 modes.
In these cases, the Input Capture Register function is disabled. Unlike OCR1A,
ICR1 is not buffered, but is immediately overwritten.
Timer/Counter1 Interrupt Mask Register TIMSK1:
- In TIMSK1, you enable the interrupts for the Input Capture function (ICIE1),
the Output Compare Matches (OCIE1B, OCIE1A), and the Timer Overflow (TOIE1).
The “IE” stands for “Interrupt Enable”.
If interrupts are enabled:
TIMER1_CAPT_vect for Input Capture
TIMER1_COMPA_vect / TIMER1_COMPB_vect for Compare Match
TIMER1_OVF_vect for Timer Overflow
Timer/Counter1 Interrupt Flag Register TIFR1:
- If the interrupts are enabled, the corresponding bits are set in TIFR1.
Output Compare Pins OC1A and OC1B:
- Timer1 has two Output Compare pins
- The behavior of the Output Compare pins depends on the setting of the WGM1 bits
and the Compare Output bits in TCCR1A and TCCR1B.
Settings in TCCR1A and TCCR1B:
- Wave Form Generation Modes - 16 modes
- Clock Select Bits / Prescaler
- Compare Output Mode Bits
*/
/*
CTC Mode
“Clear Timer on Compare Match”, Instead of 0xFFFF, Top is either OCR1A (WGM mode 4) or ICR1 (WGM mode 12).
Top determines the frequency. In CTC mode, counting is only upwards. After peaking, TCNT1 is reset to zero.
Example: Toggle LED Every .5 sec Using CTC
OCR1A = (16000000 x 1 / 1024) - 1 = 15624
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
// ISR for Timer1 Compare Match
ISR(TIMER1_COMPA_vect) {
PORTB ^= (1 << PB1);
}
int main(void) {
Serial.begin(9600);
// TCCR1A – Timer/Counter1 Control Register A
// Bits 4, 5, 6, 7: Compare Output Mode, non-PWM
// Toggle port operation, Toggle OC1A & OC1B on Compare Match
//TCCR1A |= (1 << COM1A0) | (1 << COM1B0); // Wave Form Generator: CTC Mode 4, Top = OCR1A
TCCR1A = 0x00; // Normal port operation, no output compare pin toggling of OC1A & OC1B
TCCR1B = (1 << WGM12); // CTC Mode (Mode 4)
TCCR1B |= (1 << CS12); // Set prescaler to clk/256
// Mode 12 CTC, input capture register ICR1 at TOP
//TCCR1B |= (1 << WGM13) |(1 << WGM12) | (1 << CS12) | (1 << CS10); // prescaler = 1024;
// https://eleccelerator.com/avr-timer-calculator/$0
OCR1A = 31250; // 1 sec clock if 8MHz, .5 sec clock if 16MHz
//ICR1 = 15624;
TIMSK1 |= (1 << OCIE1A); // Enable interrupt on compare match
sei(); // Don't forget global interrupt enable
while (1) {
Serial.println(TCNT1);
}
return 0;
}