Modify main.c
The main.c file needs to be modified to handle the Timer1 interrupt and there are several additions to the file that are associated with the tmr1.c file that is generated by MCC.
main.c
The main.c file requires a few lines to be uncommented for the interrupt to work properly. To enable the interrupt to work, Global Interrupts and Peripheral Interrupts need to be enabled.
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
The main loop doesn't require any additional code beyond the default while(1) loop. The Interrupt Service Routine will handle the changing of the I/O pin.
while (1)
{
// Add your application code
}
The function pointer allows the main.c file to define and contain the Interrupt Service Routine (ISR). To establish this, a function prototype declaration must be placed near the top of the main.c. In this example, the function prototype is called myTimerISR. Then the actual ISR function is added after the main while() loop. This is where the actions of the ISR are located. In this example a macro from the pin_manager.h file, D3_LED_Toggle() is used to toggle the state of the LED on the RA5 pin at every Timer1 interrupt.
void myTimerISR(void);
void myTimerISR(void){
D3_LED_Toggle();
}
tmr1.c
The MCC generated tmr1.c file contains the function pointer to allow this option of controlling the ISR within the main.c file. The TMR1_ISR function handles all the flag clearing and timer reload after an interrupt. Then it calls the TMR1_InterruptHandler(). This TMR1_InterruptHandler() is defined by the function TMR1_SetInterruptHandler(void* InterruptHandler). The function pointer is indicated by the star (*) preceding the InterruptHandler. These described sections of the tmr1.c are shown here.
void TMR1_ISR(void) { // Clear the TMR1 interrupt flag PIR4bits.TMR1IF = 0; TMR1_WriteTimer(timer1ReloadVal); if(TMR1_InterruptHandler) { TMR1_InterruptHandler(); } } void TMR1_SetInterruptHandler(void (* InterruptHandler)(void)){ TMR1_InterruptHandler = InterruptHandler; }
The interrupt handler function pointer needs to be connected to the myTimerISR() function declared in the main.c file. This is done with a single line in the main.c file right after SYSTEM_Initialize().
TMR1_SetInterruptHandler (myTimerISR); //Define interrupt Handler
Completed main.c
The final main.c code is shown below with all the Timer1 Interrupt additions to control the LED when a Timer1 interrupt occurs.
#include "mcc_generated_files/mcc.h"
void myTimerISR(void);
/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();
TMR1_SetInterruptHandler (myTimerISR); //Define interrupt Handler
// When using interrupts,set the Interrupt Enable bits
// Use the following macros to:
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
while (1)
{
// Add your application code
}
}
void myTimerISR(void){
D3_LED_Toggle();
}
/**
End of File
*/