Mission 03 / 07
Clock Warrior
One missed pulse, one lost ship. Give it a heartbeat.
On this page
01The situation
The thrusters fire blind: too early and the station drops, too late and it drifts away. It needs perfect timing again.
02Why this matters
Software can't wait precisely on its own. A timer counts clock ticks in hardware, so the chip always knows exactly when.
- Blinking & PWMLED dimming and motor speed are timer-driven pulses.
- TimeoutsA microwave stops at exactly 0:00 because a timer counted it.
- MeasuringSpeed, RPM and frequency all come from counting ticks.
03The idea in one picture
Think of it as: a car odometer behind a gearbox. The prescaler is the gear (1:16 means one turn of the wheel per 16 turns of the axle), and the overflow is the odometer rolling over to zero.
Go deeper
At 4 MHz this mission's Timer0 overflows every 1.024 ms and Timer1 every 131.072 ms (highlighted below).
8-bit timer (256 counts)
| Fosc | Bypass | 1:2 | 1:4 | 1:8 | 1:16 |
|---|---|---|---|---|---|
| 1 MHz | 256 µs | 512 µs | 1.024 ms | 2.048 ms | 4.096 ms |
| 2 MHz | 128 µs | 256 µs | 512 µs | 1.024 ms | 2.048 ms |
| 4 MHz | 64 µs | 128 µs | 256 µs | 512 µs | 1.024 ms |
| 8 MHz | 32 µs | 64 µs | 128 µs | 256 µs | 512 µs |
16-bit timer (65,536 counts)
| Fosc | Bypass | 1:2 | 1:4 | 1:8 | 1:16 |
|---|---|---|---|---|---|
| 1 MHz | 65.536 ms | 131.072 ms | 262.144 ms | 524.288 ms | 1.049 s |
| 2 MHz | 32.768 ms | 65.536 ms | 131.072 ms | 262.144 ms | 524.288 ms |
| 4 MHz | 16.384 ms | 32.768 ms | 65.536 ms | 131.072 ms | 262.144 ms |
| 8 MHz | 8.192 ms | 16.384 ms | 32.768 ms | 65.536 ms | 131.072 ms |
04Your mission
- OSCCONStart the clock. Any speed works.
- T0CONStart Timer0 as an 8-bit counter with a 1:16 prescaler.
- T1CONStart Timer1 as a 16-bit counter with a 1:8 prescaler.
Hint 1
Hint 2
PSA = 0 (bit 3) means the prescaler is used. In the prescaler bits (5:4), 00 = 1:16 and 01 = 1:8.Show the solution
- 1Step 1 — OSCCON (0x20)Set it to
0x05(0000 0101). Switch the internal oscillator on at 4 MHz (any speed wins). - 2Step 2 — T0CON (0x27)Set it to
0x03(0000 0011). Timer0: on, 8-bit mode, prescaler assigned, 1:16. - 3Step 3 — T1CON (0x28)Set it to
0x11(0001 0001). Timer1: on, 16-bit mode, prescaler assigned, 1:8. - 4Program & ExecutePress P to compile your configuration into machine code in ROM, then press E to run it. When every register matches you get Target Reached.
The same thing as a program (MOVLW loads a value into W, MOVWF copies W into a register):
MOVLW 0x05
MOVWF 0x20 ; OSCCONMOVLW 0x03
MOVWF 0x27 ; T0CONMOVLW 0x11
MOVWF 0x28 ; T1CONBit-by-bit breakdown
OSCCON0x20= 0x05
Switch the internal oscillator on at 4 MHz (any speed wins). 0x05 = 0000 0101 = SCS0 = 1, IRCF = 10
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Value | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
| Field | — | IRCF | SCS0 | |||||
- IRCF (bits 2:1) =
10→ 4 MHz - SCS0 (bit 0) =
1→ Internal oscillator on - Every remaining bit is
0: those bits are not needed for this level, but they must stay clear for the value to match.
T0CON0x27= 0x03
Timer0: on, 8-bit mode, prescaler assigned, 1:16. 0x03 = 0000 0011 = TMR0ON = 1, T08BIT = 1, PSA = 0, T0PS = 00
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Value | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| Field | — | T0PS | PSA | T0SE | T08BIT | TMR0ON | ||
- T0PS (bits 5:4) =
00→ Prescaler 1:16 - PSA (bit 3) =
0→ Prescaler ASSIGNED (inverted: 0 = assigned) - T08BIT (bit 1) =
1→ 8-bit mode - TMR0ON (bit 0) =
1→ Timer on - Every remaining bit is
0: those bits are not needed for this level, but they must stay clear for the value to match.
T1CON0x28= 0x11
Timer1: on, 16-bit mode, prescaler assigned, 1:8. 0x11 = 0001 0001 = TMR1ON = 1, T18BIT = 0, PSA = 0, T1PS = 01
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Value | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
| Field | — | T1PS | PSA | T1SE | T18BIT | TMR1ON | ||
- T1PS (bits 5:4) =
01→ Prescaler 1:8 - PSA (bit 3) =
0→ Prescaler ASSIGNED (inverted: 0 = assigned) - T18BIT (bit 1) =
0→ 16-bit mode - TMR1ON (bit 0) =
1→ Timer on - Every remaining bit is
0: those bits are not needed for this level, but they must stay clear for the value to match.
Try it: build the values
Flip the bits until each register matches the mission. It's practice only; nothing is saved.
0 of 3 registers match.
OSCCON 0x20
✗ Not yet – 2 bits differHex 0x00 Binary 0000 0000 Target 0x05 (0000 0101)
- IRCF (bits 2:1) = 00 → 1 MHz
- SCS0 (bit 0) = 0 → Internal oscillator not enabled
T0CON 0x27
✗ Not yet – 2 bits differHex 0x00 Binary 0000 0000 Target 0x03 (0000 0011)
- T0PS (bits 5:4) = 00 → Prescaler 1:16
- PSA (bit 3) = 0 → Prescaler ASSIGNED (inverted: 0 = assigned)
- T0SE (bit 2) = 0 → Selects the increment edge: not part of the win value (leave 0)
- T08BIT (bit 1) = 0 → 16-bit mode
- TMR0ON (bit 0) = 0 → Timer off
T1CON 0x28
✗ Not yet – 2 bits differHex 0x00 Binary 0000 0000 Target 0x11 (0001 0001)
- T1PS (bits 5:4) = 00 → Prescaler 1:16
- PSA (bit 3) = 0 → Prescaler ASSIGNED (inverted: 0 = assigned)
- T1SE (bit 2) = 0 → Selects the increment edge: not part of the win value (leave 0)
- T18BIT (bit 1) = 0 → 16-bit mode
- TMR1ON (bit 0) = 0 → Timer off
05How you know it worked
- 1Clock pulses arriveThe timer clock line shows the raw Fosc pulses.Screenshot coming soon
- 2The prescaler divides themThe prescaler line you chose lights up and carries the slower clock.Screenshot coming soon
- 3Count, then overflowThe counter climbs, wraps to 0, and the overflow pipe latches green.TARGET REACHEDScreenshot coming soon
Simulation note
Counting is slowed down so you can watch it; the "Overflow every…" readout shows the real period.
Stuck?
- The counter never movesThe timer is off. Set TMRxON (bit 0).
- It overflows far too fastPSA = 1 skips the prescaler. Clear bit 3.
- The period is off by a lotWrong prescaler: here
00= 1:16 and11= 1:2. - Timer0 counts to 65,535It's in 16-bit mode. Set the 8-bit switch (bit 1).
06Debrief
You just gave the ship a heartbeat.
Almost every product runs on timers: a steady tick for the main loop, PWM for motors and LEDs, timeouts for safety.
// the same idea in CT0CON = 0x03; // on, 8-bit, prescaler 1:16T1CON = 0x11; // on, 16-bit, prescaler 1:8On a real chip the same switches can sit at different bit positions; its datasheet has the map. The idea is identical.