7 Interrupts and Bits Example For Mid-range Devices
The following example code is written for a PIC16F18446 and will execute on the Curiosity Nano board using that device. Much of this example is also applicable for other devices. The code initializes timer 0 to generate an interrupt every 500 mS, toggling the on-board LED (connected to port bit RA2) 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 PIC16F18446 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 = HFINT1" // Power-up default value for COSC->HFINTOSC (1MHz)
CONFIG "CLKOUTEN = OFF" // Clock Out Enable->CLKOUT function disabled
CONFIG "CSWEN = ON" // Clock Switch Enable->Writing to NOSC & NDIV allowed
CONFIG "FCMEN = ON" // Fail-Safe Clock Monitor Enable->FSCM timer enabled
CONFIG "MCLRE = ON" // Master Clear Enable->MCLR pin is Master Clear
CONFIG "PWRTS = OFF" // Power-up Timer Enable bit->PWRT disabled
CONFIG "LPBOREN = OFF" // Low-Power BOR enable bit->ULPBOR disabled
CONFIG "BOREN = ON" // Brown-out reset enable->Enabled, SBOREN bit ignored
CONFIG "BORV = LO" // Brown-out Reset Voltage Selection->VBOR set to 2.45V
CONFIG "ZCDDIS = OFF" // Zero-cross detect disable->Disabled at POR
CONFIG "PPS1WAY = ON" // PPSLOCK cleared/set only once
CONFIG "STVREN = ON" // Stack Over/Underflow will cause a reset
CONFIG "WDTCPS = WDTCPS_31" // WDT Period Select->Divider 1:65536; software control
CONFIG "WDTE = OFF" // WDT operating mode->WDT Disabled, SWDTEN is ignored
CONFIG "WDTCWS = WDTCWS_7" // WDT Window always open (100%); software control
CONFIG "WDTCCS = SC" // WDT input clock selector->Software Control
CONFIG "BBSIZE = BB512" // Boot Block Size->512 words boot block size
CONFIG "BBEN = OFF" // Boot Block Enable bit->Boot Block disabled
CONFIG "SAFEN = OFF" // SAF Enable bit->SAF disabled
CONFIG "WRTAPP = OFF" // Application Block not write protected
CONFIG "WRTB = OFF" // Boot Block Write not write protected
CONFIG "WRTC = OFF" // Configuration Register not write protected
CONFIG "WRTD = OFF" // Data EEPROM not write protected
CONFIG "WRTSAF = OFF" // Storage Area Flash not write protected
CONFIG "LVP = ON" // Low Voltage Programming enabled
CONFIG "CP = OFF" // UserNVM Program memory code protection->Disabled
GLOBAL resetVec,isr
GLOBAL LEDState ;make this global so it is watchable when debugging
PSECT bitbss,bit,class=BANK1,space=1
LEDState:
DS 1 ;a single bit used to hold the required LED state
PSECT resetVec,class=CODE,delta=2
resetVec:
ljmp start
PSECT isrVec,class=CODE,delta=2
isr:
;no context save required in software for this device
PAGESEL $ ;select this page for the following goto
BANKSEL PIE0 ;for TMR0IE and TMR0IF
;for timer interrupts, set the required LED state
btfsc TMR0IE
btfss TMR0IF
goto notTimerInt ;not a timer interrupt
bcf TMR0IF
;toggle the desired bit state
movlw 1 shl (LEDState&7)
BANKSEL LEDState/8
xorwf BANKMASK(LEDState/8),f
notTimerInt:
;code to handle other interrupts could be added here
exitISR:
;no context restore required in software
retfie
PSECT code
start:
;set up the state of the oscillator and peripherals with RA2 as a digital
;output driving the LED, assuming that other registers have not changed
;from their reset state
movlw 0x33
BANKSEL TRISA
movwf TRISA
movlw 2
BANKSEL OSCFRQ
movwf OSCFRQ
;configure and start timer using interrupts
movlw 0x89
BANKSEL T0CON1
movwf T0CON1
movlw 0x1D
movwf TMR0H
clrf TMR0L
BANKSEL PIE0 ;for TMR0IE and TMR0IF
bcf TMR0IF
bsf TMR0IE
movlw 0x80
BANKSEL T0CON0
movwf T0CON0
bsf GIE
bsf PEIE
loop:
;copy the desired state to the LED port pin
BANKSEL LEDState/8
btfss BANKMASK(LEDState/8),LEDState&7
goto lightLED
BANKSEL PORTA
bsf RA2 ;turn LED off
goto loop
lightLED:
BANKSEL PORTA
bcf RA2 ;turn LED on
goto loop
END resetVec