Objective
Atimer interrupt is often used to launch an Interrupt Service Routine (ISR) that may toggle a port pin or some other function. Prescalers can be used to extend the time delay although the timer prescale limits may not produce a large enough delay. This is where a tick counter or a counter that increments on every timer overflow can be useful for creating long delays. This can be included in the ISR but within theMPLAB® Code Configurator (MCC) generated driver code for timers is a callback function that handles this tick counter automatically. By setting a callback counter value during the MCC driver setup, longer delays are easily established. This project shows how to control the Flash rate of an LED using a callback function.
Materials
Hardware Tools (Optional)
| Tool | About | Purchase |
|---|---|---|
| | |
Software Tools
| Tool | About | Installers | Installation Instructions | ||
|---|---|---|---|---|---|
| Windows | Linux | Mac OSX | |||
MPLAB® X Integrated Development Environment | | | | | |
![]() MPLAB® Code Configurator Dynamic Code Generation | | | |||
MPLAB® XC8 C Compiler | | | | | |
Exercise Files
| File | Download | Installation Instructions | ||
|---|---|---|---|---|
| Windows | Linux | Mac OSX | ||
Project and Source Files | | | | |
Curiosity Board User Guide/Schematic | | | | |
Connection Diagram
TheCuriosity board has four LEDs prewired to the I/O pins shown below. This project controls the D7 LED.
| Hardware Function | Pin | Setting |
|---|---|---|
| IO_LED_D4 | RA5 (2) | Output |
| IO_LED_D5 | RA1 (18) | Output |
| IO_LED_D6 | RA2 (17) | Output |
| IO_LED_D7 | RC5 (5) | Output |
Procedure
1
Create a Project
Create a new project and select thePIC16F1619 along with theCuriosity board andMPLAB XC8.
If this is your first project, please visit the "MPLAB® Xpress: Create a Project" page.
3
System Setup
FromProject Resources, chooseSystem Module to open theSystem Setup window within MCC.
- In the clock settings, make sure you selectINTOSC.
- Select the system clockFOSC.
- Set Internal Clock to4MHz_HF setting.
- Check thePLL Enabled box.
- The Curiosity board uses a Programmer/Debugger On-Board (PKOB) and uses a low voltage program method to program the MCU. Therefore, the low voltage programming must be enabled by checking theLow-voltage programming Enable box.
4
Timer4 Setup
Add the TMR4 peripheral to the project from theDevice Resources area of MCC. To do that, scroll down to the timer entry and expand the list by clicking on the arrow. Now, double click on theTMR4 entry to add it to theProject Resources list. Then, click onTMR4 to open the Timer4 configuration setup screen.
- Check theEnable Timer box.
- SelectClock Source FOSC/4,Postscaler 1:1, andPrescaler 1:64.
- Set Timer Period value to9.088 ms.
- Set External Reset Source toT4IN and Control Mode toRoll over pulse.
- Set Start/Reset Option toSoftware Control (this will inhibit hardware reset of timer).
- Check theEnable Timer Interrupt box.
To extend the Timer4 based delay, software overflows will use a callback function. The overflow of TMR4 will trigger an interrupt and the MCC generated TMR4 driver code will count up to the Callback Function Rate (CFR) value of events, before calling a predefined interrupt function that will then implement the ISR in themain.c file (that will be created in step 7).
To configure the callback value, enter "11" in the CFR field. This will give us about a 100 ms rate (11 × 9.088 ms = 99.968 ms).
5
Pin Module Setup
Click onPin Module in theProject Resources area. This will open up thePin Module and thePin Management Grid. Click on theRC5 Output row blue lock to turn it green.
Note: The T4IN pin will automatically be selected and show a green lock from the TMR4 setup.
Rename the I/O pin
In the Pin Module, rename the pin RC5 to "IO_LED_D7". Only theOutput box should be checked.
6
Generate Driver Code
Click onGenerate underProject Resources to have the MCC create the drivers and a basemain.c file for the project.
7
main.c
Themain.c file needs to be updated to handle the callback function using the function pointers generated by the MCC drivers. The function pointers allowmain.c to handle all operations without having to modify the driver code.
The first modification is to addvoid myTimer4ISR(void); right after the#include mcc_generated_files/mcc.h.
#include "mcc_generated_files/mcc.h"void myTimer4ISR(void);This defines the name of the ISR that will be created to control the LED.
Now, the Timer4 driver default Interrupt Handler has to be connected to the ISR defined inmain.c.. This is handled by adding the lineTMR4_SetInterruptHandler (myTimer4ISR);, right after theSYSTEM_Initialize function.
// initialize the device SYSTEM_Initialize(); TMR4_SetInterruptHandler (myTimer4ISR); //Define interrupt HandlerRemove the double backslash comment markers from Global and Peripheral Interrupt Enable functions:
// INTERRUPT_GlobalInterruptEnable();
// INTERRUPT_PeripheralInterruptEnable();
This action will include a call to the predefined macros and enable interrupts.
// Enable the Global Interrupts INTERRUPT_GlobalInterruptEnable();// Enable the Peripheral Interrupts INTERRUPT_PeripheralInterruptEnable();Finally, define what the ISR does when the number of callbacks is complete and the interrupt is processed. For this, a macro that was created in the MCC generatedpin_manager.h file is used. The macro selected will toggle the LED from off to on and on to off on each ISR call. Add themyTimer4ISR ISR after thewhile(1) loop. This will complete the modifications tomain.c required for this project.
while (1) { // Add your application code }}void myTimer4ISR(void){ IO_LED_D7_Toggle(); //Control LED}/** End of File*/9
Make sure your Curiosity board is connected to the USB port. Then, click on theMake and Program Device icon. This will build the project again and launch the programmer built into the Curiosity board. In theOutput window, you should see a series of messages and when successful, it will end with a "Programming and Verify Successful" message.
Output Window:
Connecting to MPLAB Starter Kit on Board...Currently loaded firmware on Starter Kit on BoardFirmware Suite Version.....01.41.07Firmware type..............Enhanced MidrangeTarget detectedDevice ID Revision = 2004The following memory area(s) will be programmed:program memory: start address = 0x0, end address = 0xbfconfiguration memoryProgramming...Programming/Verify completeIf it's the first time the programmer is connected to the board, the programming tool may need to download the proper operating firmware for the exact device. You may see a series of messages if this occurs. This should only happen once.
Downloading Firmware…
Downloading bootloader
Bootloader download complete
Programming download…
Downloading RS…
RS download complete
Programming download…
Downloading AP…
AP download complete
Programming download…
Firmware Suite Version…..01.34.11
Firmware type…………..Enhanced Midrange
Results
The D7 LED will begin to blink on the Curiosity board. This shows that the callback function is working and controlling the blink rate of the LED. To prove that to yourself, go back to the TMR4 setup window in MCC and change the callback to a larger value of 55,Generate the drivers again, thenMake and Program the device. This will flash the LED at the slower rate of a half-second on/off.
Analysis
Using the callback function generated in the TMR4 driver code simplifies creating interrupt delays. It reduces the ISR in your main code to just the action you want to implement when the time delay (or the number of interrupts) has occurred.
Conclusions
Try different callback functions and also modify the ISR to do other things, such as possibly controlling more than one LED. These modifications will help you better understand how useful callback functions can be when using interrupts.










