BruceExample

Example by Bruce
7-Aug-2010



PIC16F690

@ __CONFIG _FCMEN_OFF & _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF

DEFINE OSC 8
DEFINE NO_CLRWDT 1   ' PBP doesn't clear WDT automatically

LED VAR PORTA.4      ' LED on RA4
LED = 0              ' LED off at POR

PORTA = 0
PORTB = 0
TRISB = %01110000    ' RB6/RB5 SW1/SW2 switch inputs, RB4 input
TRISA = %00000100    ' RA2 SW3 switch input

SW1 VAR PORTB.6      ' Alias switch input pins
SW2 VAR PORTB.5
SW3 VAR PORTA.2
IOC_FLAG VAR INTCON.0 ' Alias RABIF interrupt flag bit

SwitchVal VAR BYTE   ' Holds value of all switches
Mode VAR BYTE        ' Holds current mode
GP VAR BYTE          ' GP var
BlinkTime VAR BYTE   ' Blink LED this number of times

S1 CON %00000110     ' Value when SW1 is pressed
S2 CON %00000101     ' SW2 pressed
S3 CON %00000011     ' SW3 pressed

ANSEL = 0            ' A/D disabled
ANSELH = 0
CM1CON0 = 0          ' Comparators disabled
CM2CON0 = 0

OPTION_REG.7 = 0     ' enable weak pullups
WPUA = %00000100     ' weak pullups on RA2
WPUB = %01100000     ' weak pullups on RB5 & RB6

OSCCON = %01110000   ' 8MHz internal osc

' Setup individual IOC bits for pins used
IOCA = %00000100     ' RA2 int-on-change enabled
IOCB = %01100000     ' RB6 and RB5 int-on-change enabled

Mode = 0

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

ASM
INT_LIST  macro ; IntSource,    Label,         Type, ResetFlag?
    INT_Handler  RABC_INT,  _Switch_Interrupt,   PBP,  no  
    endm
    INT_CREATE       ; Creates the interrupt processor
ENDASM

   GOSUB Switch       ' Check switches before enabling IOC   
@ INT_ENABLE RABC_INT ; Enable 'Int On Change' interrupts

Main:
  IF IOC_FLAG THEN   ' Has a switch been pressed?
     GOSUB Switch    ' Yes. Wait for it to be released
     GOTO Process    ' Then process switch
  ENDIF
  GOTO Main          ' Else loop to Main until switch-press

Process: ' Get current mode
  SELECT CASE SwitchVal
         CASE S1      
              Mode = 1  ' SW1 pressed
         CASE S2
              Mode = 2  ' SW2 pressed
         CASE S3
              Mode = 3  ' SW3 pressed
         CASE ELSE
              Mode = 0  ' Non-supported switch pattern
  END SELECT

  ' Get BlinkTime for LED to show current mode
  SELECT CASE Mode
         CASE 0
              BlinkTime = 0
         CASE 1
              BlinkTime = 1
         CASE 2
              BlinkTime = 2
         CASE 3
              BlinkTime = 3
  END SELECT

Blink:   
  IF BlinkTime != 0 Then
     FOR GP = 1 TO BlinkTime
         HIGH LED
         PAUSE 250
         LOW LED
         PAUSE 250
     NEXT
  ENDIF

  GOSUB Switch  ' Check for a switch being held down before enabling IOC

  ' Re-enable interrupts after previous switch has been processed
  @ INT_ENABLE RABC_INT

  GOTO Main          ' Loop forever

Switch:
  ' Wait for all switches up
  WHILE SW1 = 0 : WEND  ' Wait until all switch inputs = 1
  WHILE SW2 = 0 : WEND  ' and read ports to clear mismatch
  WHILE SW3 = 0 : WEND 
  IOC_FLAG = 0          ' Clear the int-on-change flag bit
  RETURN                ' Return

Switch_Interrupt:
  SwitchVal = 0         ' Clear previous switch state
  SwitchVal.0 = SW1     ' Get new switch states
  SwitchVal.1 = SW2
  SwitchVal.2 = SW3
  @ INT_DISABLE RABC_INT ' Disable further IOC interrupts
  @ INT_RETURN           ' until switch has been processed

  END
Page last modified on March 08, 2018, at 11:24 PM