1.
The diagram of Fig-1 is posted for the readers looking for a brief architecture of the TImer/Counter Module of the MCU of UNO R3 Board. Feedbcak is welcome to improve the diagram.
Figure-1:
2.
Preset Count Concept (TC1)
fullCount = presetCount + actualCount
Figure-2:
3.
Normal Mode Operation of TC1
In Normal Mode Operation the counter keeps counting in te upward direction, and it simply overruns when passes its maximum 16-bit value (MAX = 0xFFFF) and then restarts from the BOTTOM (0x0000) or forced preset count.
If interrupt enable bits are active, then there can be three interrupt points in a single counting process (Fig-3).
Figure-3.
4
Testing the Interrupts of Fig-3 (for TC1)
Figure-4:
Sketch: (not tested)
volatile bool flagV;
volatile bool flagfa;
volatile bool flagfb;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(2, INPUT_PULLUP);
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 3036; //preset count
OCR1A = 18661;
OCR1B = 49911;
TIMSK1 |= (1 << TOIE1) | (1 << OCIE1A) | (1 << OCIE1B);
while (digitalRead(2) != LOW)
{
; //wait until K1 is pressed
}
TCCR1B = 0x05; //start TC1 with division factor 1024
}
void loop()
{
if (flagV == true)
{
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
flagV = false;
}
if (flagfa == true)
{
digitalWrite(11, HIGH);
delay(200);
digitalWrite(11, LOW);
delay(200);
flagfa = false;
}
if (flagfb == true)
{
digitalWrite(12, HIGH);
delay(200);
digitalWrite(12, LOW);
delay(200);
flagfb = false;
}
}
ISR(TIMER1_OVF_vect)
{
TCNT1 = 3036; //preset count
flagV = true;
}
ISR(TIMER1_COMPA_vect) //comparison is made with the content of OCR1A Register
{
flagfa = true;
}
ISR(TIMER1_COMPB_vect) //comparison is made with the content of OCR1B Register
{
flagfb = true;
}
5.
Clear Timer on Compare Match (CTC- 4) Mode Operation to Generate Square Wave Signal at DPin-9 (for TC1)
Figure-5:
Working Principle: When CTC Mode 4 is selected (WGM[13:10] = {0,1,0,0}, COM1A[1:0] = {0,1}, and pinMode(9, OUTPUT)), the Timer/Counter1 (TC1) hardware is configured to count upward from 0 and continuously compare the count value with the content of the OCR1A register (Fig-5). The value loaded into the OCR1A register is referred to as TOP, which represents the highest count value reached by TC1 before the counter is cleared and restarted in this mode of operation.
Whenever a compare match occurs at points P, Q, and so on, the logic state of digital pin 9 (OC1A) toggles. Consequently, a square wave is generated on pin 9, with its frequency determined by the following formula. The output frequency can be adjusted by changing the value stored in the OCR1A register.
f = clkSYS/(2*N*(1+OCR1A))
where: N=TC1 Clock Prescaler (1,8,64,256,or 1024),clkSYS=16 MHz
Figure-6:
Sketch: (to genertae 1 Hz square wave)
void setup()
{
Serial.begin(9600);
pinMode(9, OUTPUT);//DPin-9 (OC1B signal/pin must be set as output)
TCCR1A = 0x00; //reset register
TCCR1B = 0x00;
TCCR1B |= bit(WGM12); //1<<WGM12 ; Mode-4 TOP = OCR1A
TCCR1A |= bit(COM1A0) | bit(COM1B0); //toggle at DPin-9;
TCNT1 = 0x0000;
OCR1A = 31249;//1 Hz signal
TCCR1B |= bit(CS12); //start TC1 with clkcTC1 = 16 MHz/256 = 62500
}
void loop()
{
}
6.
Generation of Fast PWM Signal in Mode-14 Operation of TC1 (single slope)
Fast PWM signal refers to “high frequency” PWM signal; where, frequency can be varied from 1 Hz to 8 MHz by changing the values of N (TC1 clock prescaler) and ICR1 Register and the duty cycle is regulated for Ch-A by changing the value of OCR1A Register (Fig-7).
f = sysClk/(N*(1+ICR1))
==> (16 000 000)/(N*(1+ICR1))
==> (16 000 000)/(N*(1+TOP));
where:N=1,8,64,256,1024
Figure-7:
Working Principles: In Fig-7, TC1 starts counting up from BOTTOM (= 0). Frequency of the driving clock is: clkTC1 (= clckSYS/N). In non-invert mode, initially DPin-9 (OC1A) is at HIGH state and then goes to LOW state at Point-P when TC1 becomes equal to OCR1A. TC1 keeps counting up and when it becomes equal to ICR1 at Point-R, DPin-9 assumes HIGH state. As a result, there generates one cycle of the PWM signal. At Point-R, TC1 is reset to zero and begins to count up again.
Sketch: (to genertae 1 Hz signal)
- Connect RLED with DPin-9 to monitor PWM signal.
- Reset TCCR1A and TCCR1B Registers
- Select Mode-14 for Fast PWM
- Select non-inverting mode for PWM signal for Ch-A
- Compute value for ICR1 for 1 Hz using a suitable N = 256 (clkTC1 prescaler)
- Load 50% duty cycle value in OCR1A
- Start TC1 with N = 256
- Check that RLED is blinking at 1 Hz.
Codes for the above tasks:
#define OC1A 9
void setup()
{
Serial.begin(9600);
pinMode(OC1A, OUTPUT); //Ch-A
TCCR1A = 0x00; //reset
TCCR1B = 0x00; //TC1 reset and OFF
//fOC1A/B = clckSys/(N\*(1+ICR1); Mode-14 FPWM; OCR1A controls duty cycle
// 1 Hz = 16000000/(256\*(1+ICR1) N=1,8,64,256,1024 ==> ICR1 = 62500
TCCR1A |= (1 << WGM11); //Mode-14 Fast PWM
TCCR1B |= (1 << WGM13) | (1 << WGM12); //Mode-14 Fast PWM
TCCR1A |= (1 << COM1A1) | (0 << COM1A0);//Non-invert:HIGH-LOW at COMPA match
ICR1 = 62499; // TOP for 1Hz frequency
OCR1A = 31250; //= 50% duty cycle
TCNT1 = 0;
TCCR1B |= (1 << CS12);//TC1 start with N = 256; clkTC1 = 62500;
}
void loop()
{
}
7.
Changing duty cycle and frequency of Fig-7
In Fig-7, it is observed that the duty cycle of the PWM signal can be changed by shifting the position of Point-Q which depends on the content of OCR1A Register. Likewise, the frequency can be changed by changing the content of ICR1 Register, which shifts the position of Point-R.
In Fig-8, the content of OCR1A register will be changed by rotating Pot1 which feeds changing voltage to Ch-0 of the ADC. Likewise, the content of ICR1 register will be changed by rotating Pot2 which feeds changing voltage to Ch-1 of the ADC.
Figure-8:
The duty cycle and frequency of the PWM signal can be changed in the loop() function by including the following codes.
OCR1A = map(analogRead(A0), 0, 1023, 0, 62500); //duty cycle: 0% to 100%
The value of OCR1A can also be loaded at time Point-P (Fig-7) when there occurs an interrupt due to Compare Match – A event. The codes are:
bitSet(TIMSK1, OCIE1A); //COMPA interrupt is enabled
ISR(TIMER1_COMPA_vect)
{
OCR1A = map(analogRead(A0), 0, 1023, 0, 62500); //duty cycle: 0% to 100%
}
The value of ICR1 Register can also be loaded at time Point-R(Fig-7) when there occurs an interrupt due to Capture Match. The codes are:
bitSet(TIMSK1, ICIE1); //Input Capture interrupt logic is enabled Fig-11.12
ISR(TIMER1_CAPT_vect)
{
ICR1 = map(analogRead(A1), 0, 1023, 62499, 1); //f = 1 Hz to 31250 Hz
}
TOP is defined as the highest value in the count sequence at which compare match occurs and the counter value is either reset to zero (Fg-7).
The name Single Slope (Fig-7) conversion has come from the fact that the TC1 is only counting up along the positive slope and there is no counting down.
Resolution refers to the minimum amount of time by which the duty cycle of a PWM signal can be changed. For example: consider 1 Hz signal for Fig-7. With N=256, the TOP = 62499. Hence, the resolution is 1/62500 = 16 µs (= log (TOP + 1)/log (2) = 4.8/0.30 = 16 µs).
8.
Phase Correct PWM Signal in Mode-10 Operation of TC1 (dual slope)
f = sysClk/(2*N*ICR1)
==> (16 000 000)/(2*N*ICR1)
==> (16 000 000)/(2*N*TOP));
where:N=1,8,64,256,1024;TOP=ICR1,OCR1A
In Mode 10, the Phase Correct PWM mode generates a PWM signal whose frequency can be adjusted over a wide range by changing the Timer/Counter1 (TC1) clock prescaler (N) and the value stored in the ICR1 register. The duty cycle of Channel A is controlled by changing the value of the OCR1A register. The term Phase Correct indicates that the PWM outputs on Channels A and B are generated symmetrically with respect to the timer count, resulting in closely aligned signal phases and reduced timing skew between the channels.
Figure-9:
Working Principle: Referring to Fig-9, TC1 begins counting upward from Point A. The timer is driven by the clock clkTC1 (= clkSYS/N, as shown in Fig-8). In non-inverting mode, DPin-9 (OC1A) is initially in the HIGH state. When the TC1 count becomes equal to OCR1A at Point B, OC1A transitions to the LOW state.
The timer continues counting upward until it reaches the value stored in ICR1 at Point C. At this point, counting direction reverses and TC1 begins counting downward. When the count becomes equal to OCR1A at Point D, OC1A returns to HIGH state and remains HIGH until Point E.
Consequently, one complete PWM cycle is generated over the interval A–B–C–D–E. TC1 continues counting downward until it reaches zero at Point E. The timer then resumes upward counting and initiates the next PWM cycle.
The status flags OCF1A, OCF1B (not shown), ICF1, and TOV1 are automatically set at Points B, the OCR1B compare-match point, C, and E, respectively.
... in progress











