# Picking up a cheap timer

I am currently working on ATmega328 timers. But it has maximum timer of only 16 bit. Even with a prescalar of 1024 and 16MHz clock, I can only produce a time interval of about 4 seconds. Although I can code ATmega 328 to get higher time intervals by some methods but I wish to have a 32 bit timer. Is there any microcontroller from ATMEL(I find them easy to use) which has this capability at the same or lower price?

And what are some other timer options available for longer time durations(days or hours) ?

Thanks!

• you can measure a time interval in years with an arduino .... what are you trying to do? – jsotola Aug 15 '19 at 19:08
• I wish to make an LED on every 12 hours and off for next 12 hours. I do not want additional code other than the timer related code so that the switching time is exact and not affected by the small time spent in executing any extra code. – Bhuvnesh Aug 16 '19 at 4:15

Choosing a different controller is really unnecessary. Its absolutely common to implement long delays with 16 bit timers. The only thing you need to to is using a simple additional counter variable (software pre-scaler).

Timer/Counter2 allows Clocking from external 32kHz low frequency crystal (watch crystal). So a good option would be, to use such a crystal connected to pins TOSC1 and TOSC2 (or similar).

The clock source can then be configured to increment the before mentioned hardware timer asynchronously. By setting the correct prescaler, you can achieve a Interrupt interval of exactly 1s for example. So within the ISR, you can just increment your global second counter.

Take a look at application note 1259 and/or the datasheet section for Timer/Counter2.

the following example of AVR assembly should cause you LED to blink on and off every 12 hours @ 16 MHz. Physical pin 11 for the ATMEGA328P is where the blinking occurs. You can change this by altering the location of the bit on the 7th to last line. For 8MHz clocks, divide YH and YL by 2.

jmp init

.org 0x001A
call timerHandle
reti

.org 0x0034
init:
ldi r16,0b11111111
out DDRD,r16
;load the swap value (0x283C or 10300 timer overflows)
ldi YH,0x28
ldi YL,0x3C
;Enable interrupts for the timer.
ldi r16,0b00000001
out TIMSK1,r16
;set the prescaler to 1024
ldi r16,0b00000101
out TCCR1B,r16

;loops, making sure that interrupts are enabled.
loop:
sei
rjmp loop

timerHandle:
;Compare the 16-bit registers, Executing Bottom Match if they're equal.
CP ZH,YH
BREQ topMatch
ret
topMatch:
cp ZL,YL
BREQ bottomMatch
ret
bottomMatch:
;Flip PIND7
in r17,PIND
ldi r16, 0b10000000
eor r17,r16
out PIND,r17
;Reset the counter.
clr ZH
clr ZL
ret