The Timer0 module is an 8-bit timer/counter that is included with all 8-bit PIC® MCU devices. The Timer0 is more than just a timer. It has all the following features:

  • 8-bit timer/counter register (TMR0)
  • 8-bit prescaler (independent of Watchdog Timer)
  • Programmable internal or external clock source
  • Programmable external clock edge selection
  • Interrupt on overflow
  • TMR0 can be used to gate Timer1

Below is a simplified block diagram of the Timer0 module:


The Timer0 module can be used as an 8-bit timer. In timer mode, it is incremented on every instruction clock pulse unless a prescaler is used to reduce the speed. The TMR0 register can be written via software to preload it with a value. If the TMR0 register is written, the increment is inhibited for the following two instruction cycles. This can be adjusted in the prewritten value.

Timer Mode

Timer mode is selected by clearing the TMR0CS bit of the OPTION_REG register.


Software Programmable Prescaler

A software programmable prescaler is available for exclusive use with Timer0. The prescaler is enabled by clearing the PSA bit of the OPTION_REG register. There are eight prescaler options for the Timer0 module ranging from 1:2 to 1:256. The prescale values are selectable via the PS<2:0> bits of the OPTION_REG register. In order to have a 1:1 prescaler value for the Timer0 module, the prescaler must be disabled by setting the PSA bit of the OPTION_REG register.


The prescaler is not readable or writable. All instructions writing to the TMR0 register will clear the prescaler. The prescaler is exclusively shared between the Timer0 module and the Watchdog Timer. When the prescaler is assigned to the Timer0 module, any write to the TMR0 register will immediately update the TMR0 register and clear the prescaler.

Counter Mode

In 8-Bit Counter mode, the Timer0 module will increment on every rising or falling edge of the T0CKI I/O pin. This allows the PIC® MCU to count pulses from an external clock source. The signal has voltage limits as specified in the device data sheet but will typically be the limits of the device's operating voltage.

By selecting this externally triggered counting option to the Timer0, the software can monitor the pulses from an external sensor to capture data. Timer0 has a 255 count limit before overflowing back to zero. This count can be extended by using a prescaler.

Counter Setup

8-Bit Counter mode using the T0CKI pin is selected by setting the TMR0CS bit in the OPTION_REG register to ‘1’.


The rising or falling transition of the incrementing edge for either input source is determined by the TMR0SE bit in the OPTION_REG register.


Counter Mode Synchronization

When an external clock input is used for Timer0, it must meet certain timing requirements. These requirements ensure the external clock can be synchronized with the internal instruction clock. Also, there may be a slight delay in the actual incrementing of Timer0 after synchronization.

When no prescaler is used, the external clock input is the same as the prescaler output. The synchronization of T0CKI with the internal phase clocks is accomplished by sampling the prescaler output. The T0CKI signal has to be at a high level for at least two clock periods of the system clock (Fosc) and a small RC delay of 20 nanoseconds. The signal must also be low for at least two Fosc clock periods.

When a prescaler is used, the external clock input is divided by an asynchronous ripple-counter type prescaler so that the prescaler output is symmetrical. For the external TOCKI input to meet the sampling requirement, the ripple-counter must be taken into account. Therefore, it is necessary for T0CKI signal to have a period of at least four clock periods of the Fosc clock (and a small RC delay of 40 ns) divided by the prescaler value. The only requirement on T0CKI high and low time is that they do not violate the minimum pulse-width requirement for the device (around 10 nanoseconds).

Timer0 Interrupt

The TMR0IF interrupt flag bit of the INTCON register is set every time the TMR0 register overflows from FFh to 00h, regardless of whether or not the Timer0 interrupt is enabled. This allows the software to poll the bit asynchronously. The TMR0IF bit is not automatically reset, it needs to be cleared in the software.

To enable the automatic interrupt, the Timer0 interrupt enable bit (TMR0IE) of the INTCON register must be set to '1'.

With the interrupt enabled, when the TMR0 register overflows, the CPU will direct execution to the interrupt vector which needs to hold the address of the software interrupt routine. When the overflow occurs, the Interrupt Service Routine (ISR) can preload the TMR0 register and then clear the TMR0IF bit.


Timer0 Operation During Sleep

Timer0 cannot operate while the processor is in the sleep mode. The contents of the TMR0 register will remain unchanged while the processor is in the sleep mode.

Timer0 Example using MPLAB Code Configurator

The MPLAB Code Configurator (MCC) makes setting up the Timer0 peripheral very easy. The MCC will automatically generate the code to load the proper registers and initialize the proper values to produce the desired Timer0 operation.

The best way to show how this is done is through a simple example. In this example, Timer0 is used as a time base for toggling an I/O pin. A PIC16F1825 will be used with the 4 Mhz internal oscillator and the RA2 I/O pin will toggle on every Timer0 overflow. Timer0 will be set to overflow at a 2.5 millisecond rate using a 1:32 prescaler.

Timer0 Example

The first step after launching the MCC within MPLAB® X is to select the peripherals we will use in this example to set up the System settings, Timer0 configuration, and the I/O setup.


System Setup

The System setup requires two sections to be configured - the oscillator and the configuration.
The first is the oscillator. A 4 Mhz internal oscillator is selected and the Timer0 clock sources are the internal clock.


The configuration settings include the defaults. Also, the MCLR pin is set to be a digital I/O pin so the MCLR pull-up is internal to the PIC® MCU.


Timer0 Setup

Timer0 has various options to select from. The prescaler value of 32 is selected from the drop-down menu. The period of the timer is then set to a value as close as possible to the desired 2.5 milliseconds. The interrupt will not be used, so this is left unchecked. Notice that the preload value will automatically change when the desired period is selected.


I/O Setup

The pin manager is used to select the RA2 pin. Clicking on the blue unlock for RA2 will change it to a green lock to show that pin was selected.


The I/O setup screen shows the RA2 pin parameters and this is where the pin is configured as an output by checking that box. The name of the pin could also be changed to a custom name but it will be used as the default IO_RA2 in this example.


Generate Code

The generate code button generate.png is then clicked to produce the software files. A set of source files including a main.c and a set of header files are both produced by the MCC.

The main.c file is shown below. The MCC places a SYSTEM_Initialize function at the top. This function includes all the necessary files for the Timer0 setup. In addition to that, a few commands need to be added by the developer. Within the generated code are two functions that make the code easier:


There is also a function created in the pin_manager files that automatically toggles the I/O pin:


The TMR0_HasOverflow_Occurred tests the TMR0IF bit to see if it is a one. An "if statement" is used to test the result of the TMR0_HasOverflow_Occurred function. If the result is one, indicating the TMR0 has overflowed, then the RA2 pin is toggled. Timer0 has to be re-initialized which also clears the TMR0IF bit and preloads the TMR0 register with the proper preload value to create the 2.5 millisecond delay.

The function IO_RA2_Toggle is created in the pin_manager files. This makes generating the I/O toggle quite easy as all the port register settings are handled in the pin_manager functions.


Output Waveform

The oscilloscope capture below shows the result. The RA2 pin toggles every 2.52 milliseconds. This is a little longer than the settings in the TMR0 setup screen. This is because of the time it takes to toggle the pin and then re-initialize the timer0. If the timing is critical, then the value in the Timer0 setup can be adjusted to change the preload value that produced the desired overflow time.

© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.