// PIC18 in C - Versione 0.3 - Febbraio 2016 // Copyright (c) 2014, Vincenzo Villa // Creative Commons | Attribuzione-Condividi allo stesso modo 3.0 Unported. // Creative Commons | Attribution-Share Alike 3.0 Unported // https://www.vincenzov.net/tutorial/PIC18/interrupt.htm // Reference // PIC18F2xK20 / MPLAB X IDE v3.25 / XC8 1.35 // Timer0 and Timer1 interrupt #include "configurationsbits-PIC18F25K20.h" #define _XTAL_FREQ 1000000 // Main clock frequency (Default: 1 MHz) #define TIMER0_VALUE 12345u // See text - ? Hz blink #define TIMER1_VALUE 6789u // See text - ? Hz blink #define MYDELAY __delay_ms(50) // 50 ms delay void configureRegisters(void); // Configure PIC18 registers void main(void) { configureRegisters(); // Enable interrupt and timers GIEL = 1; // 1 = Enables all low priority interrupts GIEH = 1; // 1 = Enables all high (and low) priority interrupts TMR0ON = 1; // 1 = Enable Timer0 TMR1ON = 1; // 1 = Enables Timer1 while (1) { // "Supercar", forever for (LATC = 0b00000001; LATC != 0; LATC <<= 1) MYDELAY; // Shift left, eight times for (LATC = 0b10000000; LATC != 0; LATC >>= 1) MYDELAY; // Shift right, eight times } } // ******** ISR High Priority ******** void interrupt __high_priority my_isr_h(void) { if (TMR1IF == 1) // Interrupt from Timer1? { TMR1H = TIMER1_VALUE >> 8; // Write 8 MSB to Timer1 TMR1L = TIMER1_VALUE & 0xFF; // Write 8 LSB to Timer1 LATB5 = ~LATB5; // Change LED B5 status TMR1IF = 0; // Clear interrupt status } } // ******** ISR Low Priority ******** void interrupt __low_priority my_isr_l(void) { if (TMR0IF == 1) // Interrupt from Timer0? { TMR0H = TIMER0_VALUE >> 8; // Write 8 MSB to Timer0 TMR0L = TIMER0_VALUE & 0xFF; // Write 8 LSB to Timer0 LATB4 = ~LATB4; // Change LED B4 status TMR0IF = 0; // Clear interrupt status } } // ******** Startuo congigurations ******** void configureRegisters(void) { // ******** Configure I/O Ports ******** TRISC = 0; // Configure port C as output TRISB4 = 0; // Configure RB4 as output TRISB5 = 0; // Configure RB5 as output // ******** Configure Interrupts levels ******** RCONbits.IPEN = 1; // 1 = Enable priority levels on interrupts // ******** Configure Timer0 ******** T08BIT = 0; // 0 = Timer0 is configured as a 16-bit timer/counter T0CS = 0; // 0 = Internal instruction cycle clock (_XTAL_FREQ / 4 = 250 kHz) PSA = 0; // 0 = Timer0 prescaler is assigned. Timer0 clock input comes from prescaler output T0CONbits.T0PS = 0b001; // 1:4 prescale value for Timer0 TMR0H = TIMER0_VALUE >> 8; // Write 8 MSB to Timer0 TMR0L = TIMER0_VALUE & 0xFF; // Write 8 LSB to Timer0 TMR0IF = 0; // Clear interrupt status for Timer0 TMR0IP = 0; // 0 = Set low priority interrupt for Timer0 TMR0IE = 1; // 1 = Enables overflow interrupt for Timer0 // ******** Configure Timer 1 ******** TMR1CS = 0; // 0 = Internal clock (FOSC/4) for Timer1 T1CONbits.T1CKPS = 0b10; // 10 = 1:4 Prescale value for Timer1 T1RUN = 0; // Main system clock is derived from another source T1OSCEN = 0; // Timer1 oscillator is shut off TMR1H = TIMER1_VALUE >> 8; // Write 8 MSB to Timer1 TMR1L = TIMER1_VALUE & 0xFF; // Write 8 LSB to Timer1 TMR1IF = 0; // Clear interrupt status for Timer1 TMR1IP = 1; // 1 = Set high priority interrupt for Timer1 TMR1IE = 1; // 1 = Enables the Timer1 overflow interrupt }