std/timer — Timers¶
import std/timer
Direct control of the two general-purpose timer/counters. Timer0 is 8-bit
(counts and compare values are u8); Timer1 is 16-bit (u16). The
module covers prescaler selection, compare values, reading and writing the
count, Clear-Timer-on-Compare (CTC) mode, and enabling the compare-A interrupt.
Pair these with an Interrupts isr handler (for example
TIMER0_COMPA) to run code at a fixed rate.
Prescaler values¶
set_prescaler takes the timer’s clock-select value, which both starts
the timer and divides the CPU clock. That is why the examples pass 3 (= /64)
rather than a frequency. The mapping is the same for Timer0 and Timer1:
Value |
Clock source |
|---|---|
0 |
stopped (timer off) |
1 |
clk / 1 (no prescaling) |
2 |
clk / 8 |
3 |
clk / 64 |
4 |
clk / 256 |
5 |
clk / 1024 |
6 |
external pin, falling edge |
7 |
external pin, rising edge |
The interrupt rate in CTC mode is then
F_CPU / prescaler / (compare_a + 1). For example 16 MHz / 64 / (249 + 1)
= 1000 Hz, the configuration used below.
Timer0 (8-bit)¶
- @timer0_set_prescaler($prescaler: u8)¶
Select Timer0’s clock source/prescaler using the timer’s clock-select bit pattern (e.g. the value choosing /1, /8, /64, /256, /1024).
- @timer0_set_compare_a($val: u8)¶
Set the Output Compare A value. In CTC mode the timer resets when the count reaches this value.
- @timer0_set_compare_b($val: u8)¶
Set the Output Compare B value.
- @timer0_read() -> u8¶
Return the current counter value.
- @timer0_write($val: u8)¶
Set the counter to
$val.
- @timer0_ctc_mode()¶
Put Timer0 into Clear-Timer-on-Compare (CTC) mode, so it counts up to compare A and resets, giving a periodic tick.
Timer1 (16-bit)¶
- @timer1_set_prescaler($prescaler: u8)¶
Select Timer1’s clock source/prescaler.
- @timer1_set_compare_a($val: u16)¶
Set the 16-bit Output Compare A value.
- @timer1_set_compare_b($val: u16)¶
Set the 16-bit Output Compare B value.
- @timer1_read() -> u16¶
Return the current 16-bit counter value.
- @timer1_write($val: u16)¶
Set the 16-bit counter to
$val.
- @timer1_ctc_mode()¶
Put Timer1 into CTC mode (counts up to compare A and resets).
- @timer1_enable_compa_int()¶
Unmask the Timer1 compare-match-A interrupt.
Example¶
A 1 kHz tick on an ATmega328P at 16 MHz (16 MHz / 64 / 250 = 1000 Hz):
target atmega328p
import std/timer
ram mut $ticks: u16 = 0 # shared between the ISR and main
isr TIMER0_COMPA { # runs on every compare-match
1 ->+ $ticks # count one tick
}
@main {
@timer0_ctc_mode() # count up to compare-A, then reset to 0
@timer0_set_compare_a(249) # reset after 250 counts (0..249)
@timer0_set_prescaler(3) # /64 -> 16 MHz / 64 / 250 = 1000 Hz
@timer0_enable_compa_int() # unmask this timer's compare-A interrupt
@sei() # globally enable interrupts
loop * { } # the ISR does the work; main just spins
}