;*******************************************************************************
; *
; Filename: Laser_Pantograph.asm *
; Date: 8/5/2014 *
; File Version: 1.0 *
; Author: The Lightning Stalker *
; Company: Lightning Industries *
; Description: Implements countdown timer and remote switch for *
; facilitation of compliance with FDA regs. *
; *
;*******************************************************************************
; *
; Revision History: *
; *
;*******************************************************************************
#define SWITCH GPIO,GP3 ; Remote switch
#define COMP GPIO,GP2 ; Comparator output
#define PS_ON shadow,GP0 ; ATX PS_ON
#define PS_ON_MASK b'00000001' ; Bitmask for PS_ON (GP2)
#define BEEP shadow,GP1 ; Have a buzzer for some output.
#define BEEP_MASK b'00000010' ; Bitmask to toggle the buzzer
#define DoIBeep Beep,0 ; boolean beeping toggle
;*******************************************************************************
; Processor Inclusion
;*******************************************************************************
#include "p10f200.inc"
#include "Debounce.inc"
; CONFIG
; __config 0xFFEB
__CONFIG _WDTE_OFF & _CP_OFF & _MCLRE_OFF
;*******************************************************************************
; Variable Definitions
;*******************************************************************************
GPR_VAR UDATA
TimerL RES 1
TimerH RES 1
TimerE RES 1
TimerW RES 1
Beep RES 1
shadow RES 1
;*******************************************************************************
; Reset Vector
;*******************************************************************************
RES_VECT CODE 0x0000 ; processor reset vector
GOTO START ; go to beginning of program
;*******************************************************************************
; MAIN PROGRAM
;*******************************************************************************
MAIN_PROG CODE ; let linker place main program
START
Reset
movwf OSCCAL ; load oscillator calibration value
bcf OSCCAL,FOSC4 ; disable FOSC/4 output on pin 3
movlw b'10011111' ; put Timer0 in timer mode, set pin 3 as GP2
option ; and enable weak pull-ups
Init
movlw PS_ON_MASK ; Clear all output (latch)
movwf GPIO ; except for GP0, which is inverted PS_ON
movwf shadow ; and output register shadow
movlw 0xff ; Set GP2 & 3 as input, GP0 & 1 as output
xorlw PS_ON_MASK
xorlw BEEP_MASK
tris GPIO ; Load TRIS
;goto Main ;***************REMOVE*********REMOVE**********REMOVE!!!!!
;Sound alarm, light LED, and begin 25 second countdown.
movlw BEEP_MASK
xorlw PS_ON_MASK ; remember, PS_ON HAS TO stay high!
movwf shadow
movwf GPIO
movlw .6 ; Sound alarm for one second
movwf TimerE
movlw .19
movwf TimerH
movlw .173
movwf TimerL
Delay1s
decfsz TimerL,f
goto Delay1s
decfsz TimerH,f
goto Delay1s
decfsz TimerE,f
goto Delay1s
movlw PS_ON_MASK
movwf shadow ; Everything off
movwf GPIO
movlw .122 ; Delay another 24 seconds
movwf TimerE
movlw .193
movwf TimerH
movlw .129
movwf TimerL
Delay24s
decfsz TimerL,f
goto Delay24s
decfsz TimerH,f
goto Delay24s
decfsz TimerE,f
goto Delay24s
goto $+1
Main
;Wait for remote signal
btfsc SWITCH ; someone pressing the switch?
goto $ + 5 ; keep going
call SwitchDebounce ; Debounce it then!
xorlw 1 ; Did it
btfss STATUS,Z ; bounce?
goto SwitchPressed ; nope.avi
goto Main
SwitchPressed
clrf shadow ; Bring laser online
clrf GPIO
LaserON
btfss SWITCH ; Switch still on?
goto LaserON ; Yes
movlw PS_ON_MASK ; No
movwf shadow ; Shut the laser off
movwf GPIO
goto Main
END ; Directive 'end of program'
Debounce.inc -
;******************************************************************************
;SwitchDebounce - Waits for switch to release and settle
;******************************************************************************
; The SWITCH must be a steady high for 10 milliseconds to be considered
; released and debounced. The debounce routine sets a 10 mSec timer and looks
; for a high SWITCH input. The timer is reset to 10 mSec for every occurance of
; a low SWITCH input.
;
; Debounce timer constants (TenMSH and TenMSL) are a function of the
; instruction execution time and number of instructions in each loop. Debounce
; time for this example is:
; Timer overhead + TenMSH * [outer loop time + (TenMSL * inner loop time)]
; or [2 + TenMSH * (5 + (TenMSL * 5))]*(4/fosc)= .010
;
; Arbitrarily choosing 99 for TenMSL we solve for TenMSH
; 2 + TenMSH * (5 + (99 * 5)) = 10,000
; TenMSH = 9998/500 ~ 20
#define TenMSH .20
#define TenMSL .99
DEBOUNCE_VAR UDATA
CountH RES 1 ; debounce counter MS byte
CountL RES 1 ; debounce counter LS byte
DEBOUNCE CODE
SwitchDebounce
movlw TenMSH ; set outer timer loop count
movwf CountH ; outer loop overhead is 2 instructions
;========== outer loop [TenMSH * 5 instruction cycles*(Inner loop time)] ======
SDA10
movlw TenMSL ; set inner timer loop
movwf CountL
;----------------- inner loop (TenMSL * 5 instruction cycles) -----------------
SDA20
btfsc SWITCH ; test SWITCH input
retlw 1 ; SWITCH was high - return nonzero status
decfsz CountL,f ; inner loop countdown
goto SDA20 ; test SWITCH while counting
;-------------------------------- inner loop ----------------------------------
decfsz CountH,f ; outer loop countdown
goto SDA10 ; reset inner loop after each outer loop count
;================================ outer loop ==================================
retlw 0 ; full countdown and no bounces achieved - exit
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.