Using TIMER1 to blink a LED once per second for 50ms

c0dehunter:
I am able to blink LED 1 sec on, 1sec off with below code. I would like to keep the LED on only for i.e. 50ms. How to achieve this?

1. What is the meaning of 'blink LED'?

'Blink of LED' consists of 4 events: (a) 'LED ON', (b) 'remain ON for a while', (c) 'LED OFF'. and (d) 'remain OFF for a while'. When these events are mapped against time axis, we get the following line diagram:
blink1-sec.png
Figure-1: Events that form a Blink

In Fig-1, we will say that the LED is blinking at '1-sec interval' when the 'ON-period + OFF-period' is equal to 1-sec.

2. Do you want to implement the events of Fig-1 using TC1 (Timer/Counter Module 1) of the MCU where the On-period is 50 ms and the OFF-period is also 50 ms? We will be blinking L (built-in LED of UNO) at 100 ms interval.

(1) Be familiar with the structure/architecture of TC1 as Timer/Counter (L circuit is added/shown as an extra)


Figure-2: Structure/architecture of TC1 as Timer/Counter

(2) TC1 is said to be working as a 'Timer 1' when its receives the clocking/counting pulses (clkTC1) from the 16 MHz oscillator via these two clock dividers: 'System clock prescaler' and 'TC1 clock prescaler'; where the 'division factor' of the former is fixed at /1 by Arduino (divide by 1) and the 'division factor' of the later is to be set by the user as needed. TCNT1 stands for 'Timer/Counter Register 1', and it is the 'software name' for TC1; TOV1 stands for 'Timer/Counter 1 overflow flag'. Please, consult the data sheets to get the meanings of the remaining symbolic names (like CLKRR, TOIE1, etc.) used in Fig-2.

(3) Configure/initialize TC1 in such a way so that TOV1 flag gets activated (Logic High is the active state) at every 50 ms. This flag will help you to change the states of L (built-in LED of UNO) from ON to OFF and vice versa. The procedures are:

(a) Configure TC1 as 'Normal Up Counter' and keep it at 'OFF' condition with the help of TCCR1A and TCCR1B Registers (see data sheets).

TCCR1A = 0x00;
TCCR1B = 0x00;

(b) Assume clkTC1 = 16 MHz/256 (62500); calculate pre-set (n) value for TCNT1 so that TOV1 flag becomes active after counting k (known figure) number of clkTC1 pulses which is equivalent to the elapsed time of 50 ms.

0x10000 (overflow condition/count of TC1) = n + k
==> 0x10000 (overflow condition of TC1 = n + 62500*50*10[sup]-3[/sup]
==> n = 0x10000 -  3125 = 0x10000 - 0x0C35 
==> n = 0xF3CB

(c) Load the value of n into TCNT1.

TCNT1 = 0xF3CB;

(d) Start TC1 with this frequency: 62500 Hz with the help of TCCR1B Register (see data sheets).

TCCR1B = 0x04;

3. The codes are:

void setup()
{
   Serial.begin(9600);
   pinMode(13, OUTPUT);
   digitalWrite(13, LOW);         //L is OFF
   TCCR1A = 0x00;
   TCCR1B = 0x00;

   TCNT1 = 0xF3CB;     //pre-set value at clkTC1 = 16 MHz/256
   TCCR1B = 0x04;       //TC1 is running
}

void loop()
{
    while(bitRead(TIFR1, 0) !=HIGH)      //checking if TOV1 flag is acive; see data sheets for TIFR1 Register
    {
         ;     //wait until TOV1 becomes active at the elapse of 50 ms time
    }
    bitClear(TIFR1, 0);                         //clear TOV1 flag
    TCNT1 = 0xF3CB;                          //reload pre-set value
    digitalWrite(13, !digitalRead(13));     //L is OFF --> ON ---> OFF ---- 
}

BTW: To be sure that the program is working, make a visible affect of the result by changing the blink interval time to 2-sec (1-sec ON-period + 1-sec OFF-period).

blink1-sec.png