Timer Programming for the PIC18 Microcontroller

Timer Programming for PIC18 Series

Introduction

Timers are an integral part of any embedded system. They are used for generating precise time delays, measuring pulse widths, counting external events, and generating waveforms like PWM for motor control. The PIC18 family is equipped with multiple timers, each with unique capabilities. In this chapter, we will focus on the three core timers: Timer0Timer1, and Timer2.

1. The Core Timers of PIC18

The PIC18 microcontroller typically contains up to five timers. However, Timers 0, 1, and 2 form the foundation. Their key features are summarized in Figure 1.

Timer Size Clock Source Key Features
Timer0 8/16-bit Internal (Fosc/4) or External (RA4/T0CKI) 8-bit prescaler, general purpose
Timer1 16-bit Internal or External (RC0/T1OSO) Dedicated low-power 32kHz oscillator, gated control
Timer2 8-bit Internal (Fosc/4) 16-bit prescaler/postscaler, PR2 match, used for PWM

Figure 1: Comparison of PIC18 Timers (Based on PIC18F452)

2. Timer0: The 8/16-bit General Purpose Timer

Timer0 is the most flexible timer. It can operate as either an 8-bit or a 16-bit timer/counter. All its functions are controlled by the T0CON (Timer0 Control) register.

2.1. T0CON Register

The T0CON register is the heart of Timer0 programming. Figure 2 shows the bit structure of the T0CON register.

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
TMR0ON T08BIT T0CS T0SE PSA T0PS2 T0PS1 T0PS0

Figure 2: The T0CON Register (Address 0xFD5)

  • TMR0ON (Bit 7): Timer0 On/Off bit.

    • 1 = Enables Timer0.

    • 0 = Disables Timer0.

  • T08BIT (Bit 6): Timer0 8/16-bit mode select.

    • 1 = 8-bit timer/counter.

    • 0 = 16-bit timer/counter.

  • T0CS (Bit 5): Clock Source Select.

    • 1 = External clock on RA4/T0CKI pin (Counter mode).

    • 0 = Internal instruction cycle clock (Fosc/4) (Timer mode).

  • T0SE (Bit 4): Source Edge Select (only for counter mode).

    • 1 = Increment on high-to-low transition.

    • 0 = Increment on low-to-high transition.

  • PSA (Bit 3): Prescaler Assignment.

    • 1 = Prescaler is NOT assigned to Timer0 (1:1). So we bypass the prescalar.

    • 0 = Prescaler is assigned to Timer0.

  • T0PS2:T0PS0 (Bits 2:0): Prescaler Rate Select bits.

T0PS2:T0PS0 Prescaler Ratio
000 1:2
001 1:4
010 1:8
011 1:16
100 1:32
101 1:64
110 1:128
111 1:256

Figure 3: Timer0 Prescaler Ratios

2.2. Calculating Delay with Timer0

To generate a delay, we must load the TMR0 register (TMR0H and TMR0L) with an initial value. The timer increments from this value until it overflows (from 0xFF to 0x00 in 8-bit mode, or 0xFFFF to 0x0000 in 16-bit mode). The overflow sets the TMR0IF flag in the INTCON register.

Formula for Delay:

Delay=(256TMR0 Value)×Prescaler×4Fosc(for 8-bit mode)

2.3. Programming Steps for Timer0

  1. Configure the T0CON register (size, clock source, prescaler).

  2. Load the initial value into TMR0L (and TMR0H for 16-bit mode).

  3. Clear the TMR0IF flag.

  4. Turn on the timer by setting TMR0ON = 1.

  5. Wait for the TMR0IF flag to become 1 (polling).

Figure 4 shows a flowchart for a simple blocking delay using Timer0 polling.

2.3. Programming Steps for Timer0

  1. Configure the T0CON register (size, clock source, prescaler).

  2. Load the initial value into TMR0L (and TMR0H for 16-bit mode).

  3. Clear the TMR0IF flag.

  4. Turn on the timer by setting TMR0ON = 1.

  5. Wait for the TMR0IF flag to become 1 (polling).

Assembly Code Example:

; Program to generate 1ms delay using Timer0 (Fosc = 10 MHz)
DELAY_1MS
; Configure Timer0
MOVLW B’11000111′ ; T08BIT=1 (8-bit), T0CS=0 (Int Clock),
; PSA=0 (Prescaler assigned), PS=111 (1:256)
MOVWF T0CON
MOVLW 0xD9 ; Load initial value for 1ms (approx)
MOVWF TMR0L
BCF INTCON, TMR0IF ; Clear overflow flag
BSF T0CON, TMR0ON ; Start Timer0

WAIT
BTFSS INTCON, TMR0IF ; Check if overflow occurred
BRA WAIT
BCF T0CON, TMR0ON ; Stop Timer0
RETURN

3. Timer1: The 16-bit Counter with Gate Control

Timer1 is a 16-bit timer/counter with an optional gated input, making it ideal for measuring the duration of external events. It also has a dedicated low-power oscillator input for Real-Time Clock (RTC) applications using a 32.768 kHz crystal.

3.1. T1CON Register

Timer1 is controlled by the T1CON register, shown in Figure 5.

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
RD16 T1RUN T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS

Figure 5: The T1CON Register (Address 0xFCD)

  • TMR1ON (Bit 0): Timer1 On/Off bit.

  • TMR1CS (Bit 1): Clock Source Select.

    • 1 = External clock on RC0/T1OSO/T13CKI pin.

    • 0 = Internal instruction cycle clock (Fosc/4).

  • T1SYNC (Bit 2): Timer1 External Clock Input Synchronization.

    • 1 = Do not synchronize (asynchronous).

    • 0 = Synchronize external clock (synchronous).

  • T1OSCEN (Bit 3): Timer1 Oscillator Enable (for RTC).

    • 1 = Oscillator enabled on RC0/T1OSO and RC1/T1OSI.

  • T1CKPS1:T1CKPS0 (Bits 5:4): Prescaler Rate Select.

    • 00 = 1:1, 01 = 1:2, 10 = 1:4, 11 = 1:8.

  • RD16 (Bit 7): 16-bit Read/Write Mode Enable.

3.2. Using Timer1 as a Counter (Event Counter)

To use Timer1 as an event counter, set TMR1CS = 1. The timer will increment on each rising or falling edge on the RC0/T1OSO pin. The edge is determined by the T1SYNC and T1OSCEN settings.

3.3. Using Timer1 with Gate Control (Pulse Width Measurement)

The T1G (Timer1 Gate) pin (RC1/T1OSI) can be used to start and stop the timer. This is ideal for measuring the width of a pulse. When T1G is high (if T1GPOL=1), the timer runs; when low, it stops. The TMR1 value at the end represents the pulse width.

4. Timer2: The 8-bit Timer with PR2 Match

Timer2 is an 8-bit timer with a unique feature: it resets when its value matches the value in the PR2 (Period Register). This makes it the perfect choice for generating PWM signals and providing time bases for other peripherals like the Master Synchronous Serial Port (MSSP).

4.1. T2CON Register

Timer2 is controlled by the T2CON register.

Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
T2OUTPS3 T2OUTPS2 T2OUTPS1 T2OUTPS0 TMR2ON T2CKPS1 T2CKPS0

Figure 6: The T2CON Register (Address 0xFCA)

  • T2CKPS1:T2CKPS0 (Bits 1:0): Prescaler Select.

    • 00 = 1:1, 01 = 1:4, 10 = 1:16.

  • TMR2ON (Bit 2): Timer2 On/Off bit.

  • T2OUTPS3:T2OUTPS0 (Bits 6:3): Postscaler Select (1:1 to 1:16).

4.2. Operation of Timer2

Timer2 increments from 0x00 until it matches the value in the PR2 register. When a match occurs:

  1. TMR2 is cleared to 0x00.

  2. The postscaler counter increments.

  3. When the postscaler reaches its specified ratio, the TMR2IF flag is set.

4.3. Programming Steps for Timer2

  1. Write a value to PR2 to set the period.

  2. Configure T2CON (prescaler, postscaler, turn ON).

  3. Clear TMR2IF flag.

  4. Wait for TMR2IF to be set.

C Code Example (XC8 Compiler):

// Generate a 1ms delay using Timer2 (Fosc = 10 MHz)
void DelayT2_1ms() {
// 1. Set Period: Tcy = 0.4us, Prescaler=1:16
// N = (Delay / (Tcy * Prescaler)) = 1ms / (0.4us * 16) = 1000 / 6.4 = 156.25
// PR2 = N – 1 = 155 (0x9B)
PR2 = 0x9B; // Set period

// 2. Configure T2CON: Prescaler=16 (10), Postscaler=1 (0000), Turn ON
T2CON = 0b00000110; // T2CKPS1:T2CKPS0 = 10 (1:16), TMR2ON = 1

// 3. Clear flag and wait
PIR1bits.TMR2IF = 0; // Clear Timer2 interrupt flag
while(!PIR1bits.TMR2IF); // Wait for match to occur

// 4. Turn off timer (optional)
T2CONbits.TMR2ON = 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *