• Pic® Basic


  • Instant interrupts

    There is on some occasions a desire to use more of Proton's command set while within an interrupt handler. To enable this Les has written some new macro commands that will save and restore all the system variables for you. Remember that in a large program they can number 30 or more, so only use these routines when you absolutely have to as the overheads saving and restoring can be quite large.

    How to use

    At the start of your program include the file “BASIC_INTS.INC” then declare the interrupt source and handler as normal. Lastly at the beginning of the handler issue the new command SYSTEM_SAVE and at the end SYSTEM_RESTORE.

    You can now use just about the full subset of Proton commands without the time and code overheads of the BASIC interrupt system.

    The file down loadable is “BASIC_INTS.INC” . and below a demo of printing while in an interrupt routine, this file will run in ISIS on the PIC18_ALCD_VHB board.

    Notes For the 16 series PIC® (18C/F…) and PROTON+ Version 3.03 onwards set the IDE highlight options for Macros to another setting than normal to highlight the new commands as such.

    ' Save ALL the compiler's SYSTEM variables and selected SFR registers before an interrupt, then restore them
    '
    ' This allows a greater subset of BASIC commands within an interrupt handler
    '
    ' For 16-bit core (18F) devices only. Using PROTON+ Version 3.03 Onwards.
    '
    ' This program can be tested using the PIC18_ALCD_VHB file in the ISIS simulator.
    '
    Include "PROTON18_4.INC" ' Use the PROTON Dev board for the demonstration

    REMINDERS = OFF
    RESERVE_RAM 127 ' Reserve enough RAM at top of memory for a worse case scenario of ALL BANKA being used for system variables
    REMINDERS = On

    Dim COUNTS As Word SYSTEM
    Dim COUNTS2 As Word SYSTEM

    Symbol TIMER1 = TMR1L.Word ' Create a WORD variable from two hardware registers
    Symbol TMR1IF = PIR1.0
    Symbol GIE = INTCON.7

    ON_HARDWARE_INTERRUPT GoTo INTERRUPT_HANDLER ' Point the interrupt vector to the subroutine "INTERRUPT_HANDLER"
    '------------------------------------------------------------------------------------------------------
    DelayMS 200 ' Wait for things to stabilise
    GoTo OVER_INTERRUPT ' Jump over the interrupt subroutine

    '------------------------------------------------------------------------------------------------------
    ' Macro to save the compiler's SYSTEM variables and selected SFR registers
    SYSTEM_SAVE MACRO-
    ASM-
    ; Context SAVE the essential registers
    movff STATUS,_RAM_END ; Save the STATUS register
    movff WREG,_RAM_END - 1 ; Save the WREG
    movff BSR,_RAM_END - 2 ; Save the bank select register
    movff FSR0L,_RAM_END - 3 ; Save low byte of FSR0
    movff FSR0H,_RAM_END - 4 ; Save high byte of FSR0
    movff FSR1L,_RAM_END - 5 ; Save low byte of FSR1
    movff FSR1H,_RAM_END - 6 ; Save high byte of FSR1
    movff FSR2L,_RAM_END - 7 ; Save low byte of FSR2
    movff FSR2H,_RAM_END - 8 ; Save high byte of FSR2
    movff PRODL,_RAM_END - 9 ; Save the multiply registers
    movff PRODH,_RAM_END - 10 ; These require saving because the compiler uses them regularly.
    movff TBLPTRL,_RAM_END - 11 ; Save the Table Pointer registers
    movff TBLPTRH,_RAM_END - 12 ; These require saving because the compiler uses them regularly.
    movff TABLAT,_RAM_END - 13 ; Save the code memory access register

    ; Save the compiler's SYSTEM variables
    lfsr 0,_RAM_END - 14 ; Point FSR0 to the next available piece of memory in high RAM
    lfsr 1,_SYSTEM_VARIABLE_COUNT - 1 ; Point FSR1 to the end of the SYSTEM variables in Access RAM
    movlw _SYSTEM_VARIABLE_COUNT ; Form a loop for the amount of system variables used
    movff POSTDEC1,POSTDEC0 ; Move the compiler's SYSTEM variables from Access RAM into high memory
    decfsz WREG,F ; Decrement and skip if zero the variable counter
    bra $ - 6 ; Keep placing variables until all done
    VARIABLE _RAM_POINTER = (_RAM_END - 14) - _SYSTEM_VARIABLE_COUNT ; Point to the finishing point of the variable save
    ENDASM-
    ENDM
    '------------------------------------------------------------------------------------------------------
    ' Macro to restore the compiler's SYSTEM variables and selected SFR registers
    SYSTEM_RESTORE MACRO-
    ASM-
    ; Restore the compiler's SYSTEM variables
    lfsr 0,_RAM_END - 14 ; Point FSR0 to the start of the system variables stored in high memory
    lfsr 1,_SYSTEM_VARIABLE_COUNT - 1 ; Point FSR1 to the end of the SYSTEM variables in Access RAM
    movlw _SYSTEM_VARIABLE_COUNT ; Form a loop for the amount of system variables used
    movff POSTDEC0,POSTDEC1 ; Move the compiler's SYSTEM variables from high memory into Access RAM
    decfsz WREG,F ; Decrement and skip if zero the variable counter
    bra $ - 6 ; Keep placing variables until all done

    ; Context RESTORE the essential registers and exit the interrupt
    movff _RAM_END - 13,TABLAT ; Restore the TABLAT register
    movff _RAM_END - 12,TBLPTRH ; Restore high byte of TBLPTR
    movff _RAM_END - 11,TBLPTRL ; Restore low byte of TBLPTR
    movff _RAM_END - 10,PRODH ; Restore high byte of PROD
    movff _RAM_END - 9,PRODL ; Restore low byte of PROD
    movff _RAM_END - 8,FSR2H ; Restore high byte of FSR2
    movff _RAM_END - 7,FSR2L ; Restore low byte of FSR2
    movff _RAM_END - 6,FSR1H ; Restore high byte of FSR1
    movff _RAM_END - 5,FSR1L ; Restore low byte of FSR1
    movff _RAM_END - 4,FSR0H ; Restore high byte of FSR0
    movff _RAM_END - 3,FSR0L ; Restore low byte of FSR0
    movff _RAM_END - 2,BSR ; Restore the bank select register
    movff _RAM_END - 1,WREG ; Restore the WREG
    movff _RAM_END,STATUS ; Restore the STATUS register
    ENDASM-
    ENDM
    '------------------------------------------------------------------------------------------------------
    ' Interrupt service routine
    INTERRUPT_HANDLER:
    SYSTEM_SAVE ' Save the SYSTEM variables and selected SFR registers
    RESET_BANK ' Reset the RAM banks first so we know where we are in RAM
    '
    ' The body of the Interrupt routine goes here
    '
    Print At 2,1, "INTERRUPT ",Dec COUNTS2," " ' Display an incrementing counter on the LCD
    Inc COUNTS2 ' Increment the counter

    SYSTEM_RESTORE ' Restore the SYSTEM variables and selected SFR registers
    Clear TMR1IF ' Clear the Timer1 interrupt flag
    retfie ' Exit the interrupt
    RESET_BANK ' Reset the RAM banks so the main program knows where it is in RAM
    '------------------------------------------------------------------------------------------------------
    ' The MAIN DEMO PROGRAM LOOP STARTS HERE
    OVER_INTERRUPT:

    Cls ' Clear the LCD
    COUNTS = 0 ' \
    COUNTS2 = 0 ' / Reset the two counting variables

    GIE = 0 ' Disable All Interrupts for now
    T1CON = %00000001 ' Turn on Timer1, prescaler = 1:1
    PIR1.0 = 0 ' Clear TMR1 interrupt flag
    PIE1.0 = 1 ' Enable TMR1 as peripheral interrupt source
    INTCON = %11000000 ' Enable global interrupts and peripheral interrupts

    While 1 = 1 ' Create an infinite loop
    PIE1.0 = 0 ' Disable the TMR1 interrupt while we print in the foreground
    Print At 1,1,"FOREGROUND ",Dec COUNTS," " ' Display an incrementing counter on the LCD
    PIE1.0 = 1 ' Re-enable the TMR1 interrupt
    Inc COUNTS
    DelayMS 300
    Wend
    contributed by Les Johnson.
  • Recent Activity

    teo-16018

    Microsoft security essentials blues

    Thread Starter: shantanu@india

    Hi, A strange thing happened just now.My Windows 7 Micrsoft Sercurity Essentials suddenly gave a warning that prplus.exe(Compiler) is a potential...

    teo Today, 19:23 Go to last post
    barak-1433

    SPI mssp

    Thread Starter: picprotonguy

    Just ordered Digital to Analog IC MCP4822 with SPI interface and immediately opened proton manual. I'm very disappointed, it looks like Proton...

    barak Today, 22:50 Go to last post
    David Barker-251

    UMC bootloader 18F46K22

    Thread Starter: shunt010

    Hi all. I am trying to build a UMC bootloader file for the 18F46K22, and it doesn't appear to work. It returns (in the error log) Error ...

    David Barker Today, 11:20 Go to last post