Interrupt Delay using Callback Function in MCC

 Objective

A timer 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 longer delays. This can be included in the ISR, but within the MPLAB® 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
Curiosity-50px.png
Curiosity
Development Board

Software Tools

Tool About Installers
Installation
Instructions
Windows Linux Mac OSX
MPLAB® X
Integrated Development Environment
swtool-28px.png
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

The curiosity 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
figure1.png

 Procedure

1

Create a Project

Create a new project and select the PIC16F1619 along with the Curiosity Board and MPLAB XC8 compiler. If this is your first time creating a project, click on the link below to expand the directions.

2

Launch MCC

Open the MPLAB Code Configurator under the Tools -> Embedded menu of MPLAB X IDE.

mcclaunch.png

3

System Setup

From Project resources choose System Module to open the System Setup window within MCC.

  • In the clock settings, make sure you select INTOSC
  • Select the system clock FOSC.
  • Set Internal Clock to to 4MHz_HF setting.
  • Check the PLL Enabled box.
  • The Curiosity Board uses a programmer/debugger on board (PKOB) and uses a Low Voltage Program method to program the MCU, therefore we must enable low voltage programming by checking the Low-voltage programming Enable box.
figure1cip.png

4

Timer 4 Setup

Add the TMR4 peripheral to the project from the the Device 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 the TMR4 entry to add it to the Project Resources list. Then click on TMR4 to open the Timer 4 configuration setup screen.

figure2cip.png
  1. Check the Enable Timer box
  2. Select Clock Source FOSC/4, Postscaler 1:1, Prescaler 1:64
  3. Set Timer period value to 9.088 ms
  4. Set External Reset Source to T4IN, Control mode setting to Roll over pulse,
  5. Set Start/Reset Option to Software Control (this will inhibit hardware reset of timer).
  6. Check the Enable 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 value of events, before calling a predefined interrupt function that will then implement the Interrupt Service Routine (ISR) in the main.c file (that will be created in step 7).

figure3cip.png

To configure the callback value, enter 11 in Callback Function Rate field. This will gives us about a 100 millisecond rate (11 × 9.088 ms = 99.968 ms).

5

Pin Module Setup

Click on the Pin Module in the Project Resources area. This will open up the Pin Module setup screen and the Pin Management Grid. Click on the RC5 Output row blue lock to turn it green.

figure4cip.png

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 screen rename the pin RC5 to IO_LED_D7. Only the Output box should be checked.

figure5cip.png

6

Generate Driver Code

Click on the Generate button in the Project Resources area of the MCC screen to have the MCC create the drivers and a base main.c file for the project.

7

main.c

The main.c file needs to be updated to handle the callback function using the function pointers generated by the MCC drivers. The function pointers allow main.c to handle all operations without having to modify the driver code.

The first modification is to add void myTimer4ISR(void); right after the mcc_generated_files/mcc.h #include.

#include "mcc_generated_files/mcc.h"

void myTimer4ISR(void);

This defines the name of the Interrupt Service Routine (ISR) that will be created to control the LED.

Now the Timer4 driver default Interrupt Handler has to be connected to the ISR defined in main.c. This is handled by adding the line: TMR4_SetInterruptHandler (myTimer4ISR); right after the SYSTEM_Initialize function.

// initialize the device
    SYSTEM_Initialize();

    TMR4_SetInterruptHandler (myTimer4ISR);  //Define interrupt Handler

Remove 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, we need to define what the ISR does when the number of callbacks are complete and the interrupt is processed. For this a macro is used that was created in the MCC generated pin_manager.h file. The macro selected will toggle the LED from off to on and on to off on each ISR call. Add the myTimer4ISR interrupt service routine after the while(1) loop. This will complete the modifications to main.c required for this project.

    while (1)
    {
        // Add your application code
    }

}
void myTimer4ISR(void){
    IO_LED_D7_Toggle(); //Control LED
}
/**
 End of File
*/

8

Build Project

Click on the Build Project Icon (the Hammer) to compile the code and you will see a BUILD SUCCESSFUL message in the output window of MPLAB X within several seconds of processing time.

Main_Build_Project.png
BUILD SUCCESSFUL (total time: 8s)

9

Make sure your Curiosity Board is connected to the USB port. Then click on the Make and Program Device icon. This will build the project again and launch the programmer built into the Curiosity Board. In the output window you should see a series of messages and when successful it will end with a Programming and Verify Successful message.

Main_Program_Target_Project.png

Output Window:

Connecting to MPLAB Starter Kit on Board...

Currently loaded firmware on Starter Kit on Board
Firmware Suite Version.....01.41.07
Firmware type..............Enhanced Midrange

Target detected
Device ID Revision = 2004

The following memory area(s) will be programmed:
program memory: start address = 0x0, end address = 0xbf
configuration memory

Programming...
Programming/Verify complete

If 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, then Make 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 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. Modifications like that will help you better understand how useful callback functions can be when using interrupts.

© 2016 Microchip Technology, Inc.
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.