Home ==> Microbeginner ==> 4. LED with Timer

Lecture 4: Blinking a LED with a timer

In this lecture will will wave Goodbye to lengthy and boring counting loops. We let the internal timer fulfill the task of counting, independant from the execution of the program.

4.0 Overview

  1. Introduction to timer hardware
  2. Hardware, components, mounting
  3. Timer in standard counting mode
  4. Timer in CTC mode
  5. Timer in 128 kcs/s mode

4.1 Introduction to timer hardware

The build-in timer (exact: timer/counter, TC0) is the most often used internal hardware component. As a versatile element, it has several different modes, depending from our needs. We will use the timer in later lectures, so in the next lectures we will use this timer in different modes to control the LED.

Different AVR devices have a different number of different counters. Those are named TC0, TC1, etc. As timers sometimes can be connected to port pins those port pins names refer to the TC number. The ATtiny13 has only one timer, but the zero in the name is inserted even though unnecessary in that case.

4.1.1 Timer

TCNT Timers in the AVRs are either 8 or 16 bit wide. They count up or, in certain modes, downwards. With 8 bits they count from decimal 0 to 255, with 16 bits from 0 to 65,535. If they reach and exceed their upper limit, they restart again at zero. Their actual count state is available by reading the port TCNT (8 bits) or the ports TCNTH and TCNTL (16 bits). Those can be written, too, and the timer counts from this changed state.

4.1.2 Timer pulse sources

There are seven different sources to connect the timer with pulses (and an eight's to switch timing/counting off). Three bits in the timer control port B, TCCRB, control which source is used. Those three bits control a multiplexer with eight inputs and control the signal that clocks the timer.


The eight different sources are:
#BinModeClock source
0000OffNo signal, counting off
1001TimerController clock
2010TimerController clock divided by 8
3011TimerController clock divided by 64
4100TimerController clock divided by 512
5101TimerController clock divided by 1,024
6110Counterexternal pin T, falling edge
7111Counterexternal pin T, rising edge

With the lines

	ldi R16,1 ; R16 to 1
	out TCCR0B,R16 ; to control port B

the timer starts with the controller clock as source, with

	ldi R16,0 ; R16 to zero
	out TCCR0B,R16 ; to control port B

the timer is stopped. The instruction "OUT" writes all eight bits to the port.

4.1.3 Timer and compare match

Comparer The whole timing and counting would only have limited sense if we were to read TCNT in a loop and react to certain values. For this task the timer has two comparers. Those compare the current state of TCNT with programmed values in OCRA and OCRB. If the value of TCNT fits with one of those certain hardware functions can be programmed or the controller can be interrupt (see later lectures for this).

4.1.4 Timer in CTC mode

CTC The obvious application of a comparer is to use the compare match to restart the timer/counter. This mode of counting is called "clear timer on compare" or CTC. With that the timer/counter resolution can be set to any desired length (below eight/sixteen bit of course).

Please note that the compare match resets the counter a) if a match occurs and b) the next counting pulse occurs. This ensures that the duration is exact and does not depend from the speed of the compare match recognition. In the example the compare register is set to nine, by which the CTC resets with a count of ten (pulse 0 to 9 = 10 pulses).

CTC is possible with all timers using the compare match A. Compare match B can then be used for other purposes. Some AVR devices have an additional port that can be used as compare match for CTC, leaving compare match A and B for other purposes.

4.1.5 Timer manipulation of pin outputs

The second frequent use of compare match ports is to set or clear port pins. With that the timer/counter can generate electrical pulses on a port pin of any desired duration and the compare match gets visible on the outside. For the ATtiny13 the port pin PB0 can be programmed to follow compare match A (the port pin's name if programmed in that way: OC0A), PB1 connects to compare match B (OC0B). To enable compare match A PB0 has to be configured as output (e.g. with sbi DDRB,DDB0) and to select the pin mode with two control bits:
Function OC0A/OC0B
00No change on port pin
01Port pin changes its polarity at Compare Match (Toggle)
10Port pin clears at Compare Match
11Port pin sets at Compare Match

Please note that this applies for the normal timing/counting mode. In other modes the control bits have different meanings.

4.2 Hardware, components and mounting

In this lecture the same hardware is used as in the previous lectures.
Home Top Introduction Hardware Standard mode CTC mode 128kcs mode

4.3 Timer with standard operation

4.3.1 Functioning

The simplest mode to program a blinker is to let the timer count to 255 with the maximum prescaler available (1,024), to compare with 255 and to toggle the output pin OC0A. With that, a blinking frequency of

1,200,000 / 1,024 / 256 / 2 = 2.29 cs/s

results. That is faster than it should be, but already in a visible range. Not really able to base a watch on, but simple.

4.3.2 Program

Here the whole program (Source code is here). It first switches PB0 to be output. Then writes 255 to the Compare A port, defines the output pin to the toggle mode and starts the timer with a prescaler value of 1,024.

; ***************************************
; * Timer to blink a LED                *
; * (C)2017 by www.avr-asm-tutorial.net *
; ***************************************
.INCLUDE "tn13def.inc"
; ---------- Registers ----------------
.def rmp = R16 ; Multi purpose register
; ---------- Timing -------------------
; Internal RC-Oscillator = 9,600,000 Hz
; Clock prescaler CLKPR  =         8
; Internal contr. clock  = 1,200,000 Hz
; TC0 precaler           =     1,024
; TC0 tick               =     1,171.875 cs/s
; TC0 cycle              =       256
; TC0 single cycle       =         4.578 cs/s
; TC0 toggle frequency   =         2.289 cs/s
; ---------- Start --------------------
	; PB0 as output
	sbi DDRB,DDB0 ; PB0 as output
	; Select Compare Match
	ldi rmp,0xFF ; Match at 255
	out OCR0A,rmp ; to Compare Match A
	; toggle PB0 at Compare Match
	ldi rmp,1<<COM0A0 ; Toggle Mode
	out TCCR0A,rmp ; to control port A
	; Start timer
	ldi rmp,(1<<CS02)|(1<<CS00) ; prescaler 1024 
	out TCCR0B,rmp ; to control port B
	rjmp Loop

The instruction OUT writes the eight bits in the register to the given port.

Following the initiation sequence the controller is not needed any more for control. He is sent to an unlimited loop (Remember: the controller cannot do nothing). Note that this is a much more elegant solution than counting loops, which you can see by the fact that it is much shorter. And relieves the controller from control, making it simple to add additional tasks without interfering the timing.

TCCR0A One special feature has to be learned here. We need it from now in each source code, so we should learn this. With the formulation "ldi rmp,1<<COM0A0" the port bit COM0A0 in the port TCCR0A needs to be set to one. COM0A0 is bit 6 in this port. We could formulate this for e.g. as "ldi rmp,0b01000000" (0b is added to signal that the following is a binary number). An hour later, at the latest, we have forgotten what this binary 01000000 stands for, and we will have to consult the port list in the device databook again. Therefore the formulation "ldi rmp,1<<COM0A0" is much more convenient and transparent. The formulation means: It is essential to understand that the shifting is done during assembling only, not within the controller. The shift instruction of the controller is "LSL" (Logical Shift Left) and has a register as parameter, to be shiftet left once. So do not confuse internal assembler calculations with what the controller actually does

TCCR0B Similiarly, in the source line "ldi rmp,(1<<CS02)|(1<<CS00)" those shift-left operations are used. In that case the two results of the two shift operations are ORED ("|") and so two bits within the register are set simultaneously. CS02 is 2 (in the def.inc file), while CS00 is zero. So 0b00000100 (1<<CS02) and 0b00000001 (1<<CS00) are bitwise ORED to yield 0b00000101. This value is finally written to the register rmp. The assembler-internal OR must not be confused with the instruction OR, that ORs two registers and writes the result to the first one. The | is solely done during the assembly process.

The characters << and | are mathmatical operators of the assembler, of which there are further ones such as e.g. +, -, * and /. Those are all commands to the assembler, of which the controller is unaware.

4.3.3 Disadvantage of that solution

Even though an elegant solution, it does not blink in a 1 per second rhythm. Dividing the controllers internal clock of 1.2 Mcs/s by 1.024 in the prescaler, by 256 in the timer and by 2 in the toggle stage of OC0A, a total of 524,288, does not yield one second. The controller clock has to be reduced by approximately two to come near to 524 kcs/s.

Home Top Introduction Hardware Standard mode CTC mode 128kcs mode

4.4 Clock prescaler

4.4.1 Functioning

To reduce the controller clock speed

CLKPS bits All tiny and mega devices of the AVRs have a prescaler with which the controller clock can be adjusted. As divider factors multiples of two can be selected, before the clock signal is fed into the fetch-and-execute section of the controller. This pre-scaling is done no matter which clock source is selected by setting the fuses of the controller.

In the default case, the internal RC oscillator is selected as clock source. By use of a prescaler value of 8 this leads to the controller's default clock of 1.2 Mcs/s. The prescaler value of 8 is set by the fuse CKDIV8, which is by default set. If we clear that fuse, the controller runs at 9.6 Mcs/s clock speed. See the fuse setting in course 1. Please be aware that at very low operating voltages the 9.6 Mcs/s speed does not work in the ATtiny13V type! To set that fuse again, apply a higher operating voltage of e.g. 5 V temporarily.

CLKPR Even with the fuse CKDIV8 set, we can override this setting by programming the CLKPS bits in the port CLKPR. So we can select 4.8 or 2.4 Mcs/s as clock frequency, but even down to 9.6 Mcs/s divided by 256 = 37.5 kcs/s are possible. The unintended programming of the port CLKPR is protected. First we have to set the enable bit CLKPCE in CLKPR, with all other bits cleared. Immediately after that we can write CLKPR again with the desired CLKPS settings (with CLKPCE cleared).

To set a prescaler value of 32 the following code has to be executed:

	ldi R16,1<<CLKPCE ; Program Enable Bit to one
	out CLKPR,R16 ; write to port CLKPR
	ldi R16,(1<<CLKPS2)|(1<<CLKPS0) ; Prescaler = 32  
	out CLKPR,R16 ; write to port CLKPR

Now the controller runs at a speed of 9.6 Mcs/s / 32 = 300 kcs/s clock frequency. But be aware that the reduction of that speed requires a smaller ISP frequency when accessing the controller via the programming interface (e.g. 75 kcs/s), otherwise error messages occur.

Operating current at high frequencies By reducing the clock the controller is a lame duck. One does that if you want to reduce current requirements. The operating current is approximately linear with the clock frequency, as the diagram from the databook shows.

Operating current at low frequencies This linearity is even more exact at small clock frequencies. At 300 kcs/s the operating current is reduced to mere 0.3 mA at 4.8 V. The battery or rechargeable battery that you use will be happy and operate very much longer (if you do not drive 10 additional LEDs).

Controller sleeping

Current requirements idle A further method to reduce current requirements is to not infinitely loop but to send the controller to sleep. In that mode further reading of code from the flash memory, decoding and execution of instructions is suspended completely. This sleep mode is called "idle".

This idle state can be switched on by setting the Sleep-Enable-Bit in the port MCUCR (Micro controller universal control register) and by executing the SLEEP instruction. Like this:

	ldi R16,1<<SE ; Set sleep enable bit to one
	out MCUCR,R16 ; to universial control port
	sleep ; go to sleep

In our case the controller sleeps and no wakeup call other than the RESET will wake him up. Other wakeup mechanisms are shown in later lectures.

Timer in CTC mode

The comparer A of the timer/counter can be used for an additional operating mode, the CTC (Clear Timer on Compare match) mode. In our case we can use this to divide the clock frequency by factors that are not multiples of two. With that we come closer to a blinking in a second.

Timer modes This table shows all modes of the timer/counter in an ATtiny13. The CTC mode can be selected by setting the WGM1 bit. The maximum value that the timer has (TOP) is the number that is stored in port OCRA. After that the timer resets to zero with the next timer clock signal.

WGM bits The three WGM bits WGM02, WGM01 and WGM00 of timer 0 are distributed over the two ports TCCR0A and TCCR0B. As we only need to set WGM01 to one and COM0A0 to toggle the output pin, we again use (1<<WGM01)|(1<<COM0A0).

4.4.2 Program

The mighty program is listed here, the source code is here). First the clock frequency is changed, then port bit PB0 is switched to output, then the timer is configured and finally the controller is send to sleep.

; ***************************************
; * LED blinker with 300 kcs/s and CTC  *
; * (C)2017 by www.avr-asm-tutorial.net *
; ***************************************
.INCLUDE "tn13def.inc"
; ------ Register ---------------------
.def rmp = R16 ; multi purpose register
; ------ Timing -----------------------
; Internal RC oscillator = 9.600.000 cs/s
; Prescaler CLKPR        =        32
; Clock controller       =   300.000 cs/s
; Prescaler TC0          =     1.024
; Timer tick TC0         =       292.97 cs/s
; Timer CTC value        =       146
; Clock freq. CTC-OC0A   =         2.006 cs/s
; Frequency OC0A toggle  =         1.003 cs/s
; ------ Constants -------------------
.equ fRC = 9600000 ; Controller RC oscillator
.equ pClk = 32 ; Clock prescaler
.equ pTC0 = 1024 ; TC0 prescaler
.equ pCtc = fRC / pClk / pTC0 / 2 ; CTC divider
.equ cCtc = pCtc - 1 ; CTC value
; ------ Program start ----------------
	; To reduce the clock frequency
	ldi rmp,1<<CLKPCE ; CLKPR write enable
	out CLKPR,rmp ; to CLKPR port
	ldi rmp,(1<<CLKPS2) | (1<<CLKPS0) ; Prescaler = 32
	out CLKPR,rmp ; to CLKPR port
	; PB0 as output
	sbi DDRB,DDB0 ; Data direction output
	; Programming the timer and timer start
	ldi rmp,cCtc ; The CTC compare match value ...
	out OCR0A,rmp ; ... to the Compare A port
	ldi rmp,(1<<COM0A0) | (1<<WGM01) ; Toggle OC0A, CTC mode
	out TCCR0A,rmp ; to timer control port A
	ldi rmp,(1<<CS02) | (1<<CS00) ; Prescaler 1024
	out TCCR0B,rmp ; to timer control port B
	; Sleep mode
	ldi rmp,1<<SE ; Sleep mode idle
	out MCUCR,rmp ; to universal control port
	sleep ; send controller to sleep
	nop ; do nothing after wakeup
	rjmp Wakeup ; send controller to sleep again
; End of source code

Do not forget: the controller now works at 300 kcs/s clock, the ISP frequency has to be reduced to access the controller via ISP.

4.4.3 Advantages and drawbacks

The current requirements of the controller is strongly reduced, by reduced clock speed and by idle sleep mode. To further reduce the current we can reduce the operating voltage down to e.g. 3.3 V.

A drawback is that we missed the exact second. The deviation is much smaller than the inaccuracy of the internal RC generator from its nominal frequency (+/-10%), but for a watch we would need an external crystal oscillator.
Home Top Introduction Hardware Standard mode CTC mode 128kcs mode

4.5 Timer in 128kcs/s mode

The ATtiny13 has an additional internal RC oscillator that can be selected as clock source by setting fuses. This oscillator has a frequency of 128 kcs/s. This can be divided by the use of the CLKPR port down to 500 cs/s. Do that only in case you own a programmer that can run at less than 125 cs/s ISP frequency. The AVR-ISP-mkII can go down to 50.1 cs/s, so would be suitable for that purpose.

4.5.1 Functioning

With a clock frequency of 128 kcs/s the clock has to be divided by 64,000 to reach a toggle frequency of 2 cs/s. With a TC0 prescaler value of 1,024 the frequency would be 62.5 cs/s, an odd number. With 256 as prescaler value the CTC has to be adjusted to 250 pulses to reach 2 cs/s, which is manageable with the 8 bit timer TC0.

4.5.2 Program

The program is similar to the previous, only the timer prescaler and the CTC value are different. The source code is here.

Before we transfer the hexcode we should set the CKDIV8 fuse.

; *****************************************
; * Blink LED with timer at 128 kcs clock *
; * (C)2017 by www.avr-asm-tutorial.net   *
; *****************************************
.INCLUDE "tn13def.inc"
; ------- Register -----------------------
.def rmp = R16 ; multi purpose register
; ------- Timing -------------------------
; Internal RC oscillator   = 128.000 cs/s
; Clock prescler CLKPR     =       1
; Internal clock frequency = 128.000 cs/s
; TC0 prescaler            =     256
; TC0 timer tick           =     500 cs/s
; TC0 CTC divider          =     250
; TC0 toggle frequency     =       1 cs/s
; --------- Constants --------------------
.equ cCtc = 250-1
; --------- Programm ---------------------
	; PB0 as output
	sbi DDRB,DDB0 ; Port bit as output
	; Timer Compare Match A to 250
	ldi rmp,cCtc ; Match A value
	out OCR0A,rmp ; to Match port A
	; Timer as CTC and toggle output A
	ldi rmp,(1<<COM0A0)|(1<<WGM01) ; Toggle and CTC
	out TCCR0A,rmp ; to timer control port A
	ldi rmp,1<<CS02 ; Prescaler to 256
	out TCCR0B,rmp ; to timer control port B
	; Sleep mode
	ldi rmp,1<<SE ; Sleep mode idle
	out MCUCR,rmp ; to universial control port
	; Sleep loop
	sleep ; send to sleep
	nop ; after wakeup
	rjmp Wakeup
; End of source code

Fuse 128kcs If the hexcode is transferred to the tiny the blinking of the LED is hectic, because the clock frequency is still 1.2 Mcs/s. Now we have to change clock to 128 kcs/s. To do that we select this oscillator by setting the fuses and clear the CKDIV8 fuse. After transferring the fuses the 1-second-blinking of the LED should occur.

4.5.3 Advantages and drawbacks

Now the divider has exactly 1.000000 cs/s. On the accuracy of the internal 128 kcs/s oscillator not much is published by ATMEL. The voltage and temperature dependancy of the frequency lets expect an accuracy of -10%. At least the whole controller now is at current requirements of less than one fiftieth of the LED.

Home Top Introduction Hardware Standard mode CTC mode 128kcs mode

©2017 by http://www.avr-asm-tutorial.net