Timer Driver Library for MPLAB® Harmony v2

The MPLAB® Harmony Timer Driver library provides a high-level interface to the PIC32 Timer peripherals. The library provides interfaces to support:

  • System Interaction
  • Sync Mode Setup
  • Period Modification
  • Counter Modification
  • Client Core Functionality
  • Client Alarm Functionality

There are two kinds of Timer Drivers: Static and Dynamic.

Static Timer Drivers

Capabilities of a Static Timer Driver:

  • The Timer Static Driver provides a basic set of timer access functions such as read, write, start, stop, etc.
  • When a Static Driver is used, the project is configured with unique APIs to access each timer instance. To access a timer, you will call a function whose name is determined by the timer driver instance number.
  • Harmony generates a "stub" Interrupt Service Routine (ISR) for each timer with a static driver. You will code the application's ISR functionality into the stub ISRs. These ISRs are set during development and cannot be changed at run time.


  • Static Timer Drivers offer a straight forward, easy to understand interface.
  • It minimizes interrupt latency.


  • The Static API forces you to use different functions to control each Timer Driver (minimal hardware abstraction).
  • If circumstances force the developer to re-allocate the timers between tasks using Static Drivers will require changes in the application code.
  • ISRs cannot be changed at run time. This limits the timer's ability to alter its performance in response to run-time conditions.

Static Driver API Assignment

Static Driver APIs reference the hardware timers by driver instance (e.g. DRV_TMR0) rather than by the timer peripheral number (e.g. Timer2). You will use the MPLAB Harmony Configurator (MHC) to determine which specific hardware peripheral timer is associated with each timer driver instance.


Interrupt Processing with Static Timer Drivers

For each timer configured with a Static Driver, Harmony inserts code to create an ISR and instructs the linker to place the ISR at the appropriate vector address. Inserted into these ISRs is code to clear the relevant interrupt request flag. You are responsible for writing the body of the ISR.


API's for Static Timer Drivers

Each timer is controlled by its own set of functions. The function names for the API contain the specific timer instance of the timer being accessed. The functions listed below all use the letter X to designate the driver instance of the timer. You can use MHC to control which timer (Timer1, Timer2, etc…) is associated with each instance.

This page states the generic function DRV_TMRx_Start as the function which starts a timer. The specific functions for starting the timers are DRV_TMR0_Start, DRV_TMR1_Start ..etc

Function Name Description
DRV_TMRx_Start() Enables the timer to run
DRV_TMRx_Stop() Stops the Timer
DRV_TMRx_CounterClear() Loads the timer with the value of ZERO
DRV_TMRx_CounterValueSet() Sets the Timer value
DRV_TMRx_CounterValueGet() Reads the Timer's current value.
DRV_TMRx_Initialize() Calls individual PLIB commands to configure timer SFRs

Dynamic Timer Drivers

Capabilities of the Dynamic Timer Driver

  • The Dynamic Timer Driver is a set of API's allowing you to control any PIC32 timer similar to those offered by the Static timer Driver. The Dynamic Driver offers you more options for application management than a Static Driver.
  • Applications written using Dynamic Drivers do not need to know the timer number they are accessing. Access to the timers uses run-time retrieved 'handles'. The hardware abstraction facilitated by the handles allows code to be generated that can be transparently run using any available PIC32 timer.
  • The functions called by the Interrupt Service Routines can be assigned or changed at run-time by the application, allowing a timer to be used by several different tasks.
  • You are not required to have foreknowledge of the system clock speed when designating the period of a timer interrupt. Dynamic Drivers have the capability of allowing the application to designate only the desired frequency of the interrupt. This allows applications with fixed-period interrupts to maintain their performance characteristics, even if they are migrated to another PIC32 with different clock speed.
  • Timer interrupts can be set as continuous or 'one-time' by the application.
  • When working with the Timer System Service, Dynamic Drivers permit a single timer to initiate multiple interrupt service routines, with each of these ISRs having their own period.

Timer Setup and Hardware Abstraction

Harmony Projects contain a data structure called sysObj which consists of one pointer for each peripheral defined with a Dynamic Driver. The sysObj entries for timers are: sysObj.drvTmr0, sysObj.drvTmr1, and sysObj.drvTmr(N-1) (where N is the number of timers configured with a dynamic driver).

The initialization function DRV_TMR_Initialize(… ) initializes the timer's register and loads the address of the timer into sysObj.

Before an application can use a timer, it must receive a handle from the function DRV_TMR_OPEN(..). DRV_TMR_Open() returns a numeric handle if the timer is available. Once an application opens a timer, all subsequent calls to the timer are made referencing the handle.


Interrupt Processing with a Dynamic Timer Driver

  • MHC will create and populate the individual interrupt vectors for Dynamic timers. Each of these interrupt vectors consists of a call to the shared timer ISR DRV_TMR_Tasks_ISR.
  • The system object sysObj.tmrX of the timer generating the interrupt, is passed as a parameter to DRV_TMR_Tasks_ISR by the code in the interrupt vector.
  • After some error checking, the shared timer ISR calls the user functions designated as the "Registered" callback function for the timer.
  • You are responsible for writing and registering the function to execute on a timer interrupt.

Setting up Your ISR

In order for a function to be called by the shared timer ISR, your function must be set at the Registered Alarm Callback function for the timer. The function DRV_TMR_AlarmRegister causes your function to be called by the shared ISR.

Parameter Description
handle Handle returned from DRV_TMR_Open
divider The value to divide the timer clock source to obtain
the required alarm frequency.
isPeriodic Flag indicating whether the alarm should be one-shot or periodic.
context An optional value to be passed to the callback function.
Can be 0 if not needed.
callback The function to be called on time out.
The callback function must have the following parameters:
void myISR (uintptr_t context, uint32_t alarmCount)

 Learn More

Harmony Timer Tutorial
Learn more >
Example Code and Projects
Learn more >
Entire Timer Driver Interface
Learn more >
Timer Hardware Description
Learn more >
© 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.