8 Interrupts and Bits Example For PIC18 Devices
The following example code is written for a PIC18F47K42 and will execute on the Curiosity Nano board using that device. The code initializes timer 0 to generate an interrupt every 500 mS, toggling the on-board LED (connected to port bit RE0) with each event.
Note: This code example performs manual masking of instruction
operand addresses to avoid fixup overflow errors. You can alternatively have the
linker automatically truncate operand values when building, as discussed in Working with Data Banks, so that the
BANKMASK()
and PAGEMASK()
macros used in this
example are not required.An Example of Interrupts and Bits
/*
* Blink the LED on a PIC18F47K42 Curiosity Nano Board
* using the timer and interrupts to control the flash period.
*/
#include <xc.inc>
CONFIG "FEXTOSC = OFF" // External Oscillator not enabled
CONFIG "RSTOSC = HFINTOSC_1MHZ" // Reset Oscillator->HFINTOSC, HFFRQ=4MHz, CDIV=4:1
CONFIG "CLKOUTEN = OFF" // Clock out Enable->CLKOUT function is disabled
CONFIG "PR1WAY = ON" // PRLOCK cleared/set only once
CONFIG "CSWEN = ON" // Writing to NOSC and NDIV is allowed
CONFIG "FCMEN = ON" // Clock Monitor enabled
CONFIG "MCLRE = EXTMCLR" // LVP=0=>MCLR pin is MCLR; LVP=1=>MCLR on RE3
CONFIG "PWRTS = PWRT_OFF" // Power-up timer selection bits->PWRT is disabled
CONFIG "MVECEN = ON" // Multi-vector enable->Multi-vector table enabled
CONFIG "IVT1WAY = ON" // IVTLOCK cleared/set only once
CONFIG "LPBOREN = OFF" // Low Power BOR Enable bit->ULPBOR disabled
CONFIG "BOREN = SBORDIS" // BOR enabled, SBOREN ignored
CONFIG "BORV = VBOR_2P45" // Brown-out Reset Voltage->VBOR set to 2.45V
CONFIG "ZCD = OFF" // ZCD disabled; enable by setting ZCDSEN
CONFIG "PPS1WAY = ON" // PPSLOCK cleared/set only once
CONFIG "STVREN = ON" // Stack Full/underflow => Reset
CONFIG "DEBUG = OFF" // Debugger Enable->Background debugger disabled
CONFIG "XINST = OFF" // Extended Instruction Set Enable->Disabled
CONFIG "WDTCPS = WDTCPS_31" // WDT Period->Divider 1:65536; software control
CONFIG "WDTE = OFF" // WDT Disabled; SWDTEN is ignored
CONFIG "WDTCWS = WDTCWS_7" // WDT window open (100%); software control
CONFIG "WDTCCS = SC" // WDT input clock selector->Software Control
CONFIG "BBSIZE = BBSIZE_512" // Boot Block Size->Boot Block size is 512 words
CONFIG "BBEN = OFF" // Boot Block enable bit->Boot block disabled
CONFIG "SAFEN = OFF" // Storage Area Flash enable bit->SAF disabled
CONFIG "WRTAPP = OFF" // Application Block not protected
CONFIG "WRTB = OFF" // Configuration Register not protected
CONFIG "WRTC = OFF" // Boot Block not write-protected
CONFIG "WRTD = OFF" // Data EEPROM not write-protected
CONFIG "WRTSAF = OFF" // SAF not Write Protected
CONFIG "LVP = ON" // Low Voltage Programming Enable->LVP enabled
CONFIG "CP = OFF" // PFM and Data EEPROM Code Protection->Disabled
GLOBAL resetVec
GLOBAL LEDState ;make this global so it is watchable when debugging
GLOBAL __Livt ;defined by the linker but used in this code
PSECT bitbssCOMMON,bit,class=COMRAM,space=1
LEDState:
DS 1 ;a single bit used to hold the required LED state
PSECT resetVec,class=CODE,reloc=2
resetVec:
goto start
;vector table
PSECT ivt,class=CODE,reloc=2,ovrld
ivtbase:
ORG 31*2 ;timer 0 vector position
DW tmr0Isr shr 2 ;timer 0 ISR address shifted right
PSECT textISR,class=CODE,reloc=4
tmr0Isr:
bcf TMR0IF ;clear the timer interrupt flag
;toggle the desired LED state
movlw 1 shl (LEDState&7)
xorwf LEDState/(0+8),c
retfie f
PSECT code
start:
bsf BANKMASK(INTCON0),INTCON0_IPEN_POSN,c ;set IPEN bit
;use the unlock sequence to set the vector table position
;based on where the ivt psect is linked
bcf GIE
movlw 0x55
movwf BANKMASK(IVTLOCK),c
movlw 0xAA
movwf BANKMASK(IVTLOCK),c
bcf IVTLOCKED
movlw low highword __Livt
movwf BANKMASK(IVTBASEU),c
movlw high __Livt
movwf BANKMASK(IVTBASEH),c
movlw low __Livt
movwf BANKMASK(IVTBASEL),c
movlw 0x55
movwf BANKMASK(IVTLOCK),c
movlw 0xAA
movwf BANKMASK(IVTLOCK),c
bsf IVTLOCKED
;set up the state of the oscillator and peripherals with RE0 as a digital
;output driving the LED, assuming that other registers have not changed
;from their reset state
movlw 6
movwf BANKMASK(TRISE),c
movlw 0x62
movlb 57
movwf BANKMASK(OSCCON1),b
clrf BANKMASK(OSCCON3),b
clrf BANKMASK(OSCEN),b
movlw 2
movwf BANKMASK(OSCFRQ),b
clrf BANKMASK(OSCTUNE),b
;configure and start timer interrupts
movlb 57
bsf TMR0IP
movlw 0x6D
movwf BANKMASK(T0CON1),c
movlw 0xF3
movwf BANKMASK(TMR0H),c
clrf BANKMASK(TMR0L),c
movlb 57
bcf TMR0IF
bsf TMR0IE
movlw 0x80
movwf BANKMASK(T0CON0),c
bsf GIEH
loop:
;set LED state to be that requested by the interrupt code
btfss LEDState/8,LEDState&7,c
goto lightLED
bsf RE0 ;turn LED off
goto loop
lightLED:
bcf RE0 ;turn LED on
goto loop
END resetVec