;******************************************************************* ; Control program for "ICEBREAKER" project ; Includes the NEW 4-MHz clock routine. ; Includes timed mode and manual mode, ; Includes manual mode time limit. ;******************************************************************* ; DISABLE MASTERCLEAR AND WDT WHEN PROGRAMMING. ;******************************************************************* ; ;==========COMPILER DIRECTIVES SECTION=============================== LIST p=16F628A ;Tell the assembler to use this chip include "P16F628A.INC" cblock 0x20 ;Prepare the general purpose registers count1 ;Used in delay routine counta ;Used in delay routine countb ;Used in delay routine countv ;Used in manual mode (maximum fire time limit) endc ;==========CPU EQUATES SECTION======================================= SOL Equ 0 ;Set constant for solenoid (PortB,0) SOLLED Equ 1 ;Set constant for solenoid LED (PortB,1) LEDMAN Equ 3 ;Set constant for manual mode LED (PortB,3) LEDTIMED Equ 5 ;Set constant for timed mode LED (PortB,5) POWERLED Equ 7 ;Set constant for power indicator LED (PortB,7) TRIG Equ 0 ;Set constant for trigger (PortA,0) MODESW Equ 1 ;Set constant for mode switch (PortA,1) INPORT Equ PORTA ;Set constant for INPUT port OUTPORT Equ PORTB ;Set constant for OUTPUT port ;===========DATA DEFINITIONS SETUP=================================== org 0x0000 ;Program starts here movlw 0x07 ;Setup CMCON movwf CMCON ;Disable comparators, allows for general I/O. bsf STATUS, RP0 ;Edit terminal direction assignments... movlw b'00011111' movwf TRISA ;Set PortA as all inputs movlw b'00000000' movwf TRISB ;Set PortB as all outputs bcf STATUS, RP0 ;End direction assignment setup (autoselect bank 0). ;===========MAIN PROGRAM======================================= clrf PORTB ;Ensure all outputs are off at this point. bsf PORTB, POWERLED ;Turn on the power indicator LED Loop ;Input scan routine begin here <--- nop ;Wait for 2-µS nop bcf PORTB, SOL ;Ensure the solenoid and firing LED are off! bcf PORTB, SOLLED btfss PORTA, MODESW ;Bit check, mode switch (skip next if high)... goto Manmode ;If low, jump to "Manual-mode" goto Timedmode ;If high, jump to "Timed-mode" ; The program returns to this^^ routine each scan cycle. ; ;===========ACTION SUBROUTINES=================================== Manmode bsf PORTB, LEDMAN ;Set the correct mode LED bcf PORTB, LEDTIMED btfsc PORTA, TRIG ;Bit check, trigger (skip next if low) goto Loop ;If high, loop forever. movlw d'20' ;If low, prepare to debounce Call Delay ;Debounce delay btfsc PORTA, TRIG ;Post-debounce...bit check, trigger (skip next if low) goto Loop ;If high, false positive...loop and start over. bsf PORTB, SOL ;If low, set firing bits bsf PORTB, SOLLED clrf countv ;Reset the valve override counter movlw d'25' ;Prepare valve override counter value (number of loops) ; (20-ms)(25 loops) = 500ms movwf countv Manfire ;Loop to this line when keeping sol energized movlw d'20' ;Wait this milliseconds between trigger checks (loop time) Call Delay btfsc PORTA, TRIG ;Bit check, trigger (skip next if high) goto Firedis ;If high, cease firing! Decfsz countv, f ;If low, decrement valve dwell counter, skip next if ==0 goto Manfire ;Loop counter not done yet, loop and do again goto Firedis ;Counter has expired, auto shutoff solenoid and trigger. ; Timedmode bcf PORTB, LEDMAN ;Set the correct mode LED bsf PORTB, LEDTIMED btfsc PORTA, TRIG ;Bit check, trigger (skip next if low) goto Loop ;If high, loop forever. movlw d'20' ;If low, prepare to debounce Call Delay ;Debounce delay btfsc PORTA, TRIG ;Post-debounce...bit check, trigger (skip next if low) goto Loop ;If high, false positive...loop and start over. bsf PORTB, SOL ;If low, set firing bits bsf PORTB, SOLLED movlw d'100' ;Timed energize value in milliseconds Call Delay ;Firing time delay nop ;Firing complete, fall thru to Firedis routine.... Firedis ;Use this subroutine to cease firing and lock the trigger. bcf PORTB, SOL ;Deactivate the solenoid and LED, this mayhem has to stop! bcf PORTB, SOLLED btfss PORTA, TRIG ;Bit check, trigger (skip next if high) continuously! goto Firedis ;If low, loop and wait goto Loop ;If high, trigger has been released...master loop. ;===========GLOBAL SUBROUTINES================================= Delay ;4-MHz delay subroutine movwf count1 ;Master loop - assign this to the W value before the CALL d1 movlw 0xC7 movwf counta ;Assign "counta" (inner loop) movlw 0x01 movwf countb ;Assign "countb" 1-ms (outer loop) Delay_0 decfsz counta, f ;Decrement inner loop, skip next line if ==0 goto $+2 ;Loop and repeat until it==0 decfsz countb, f ;Inner loop complete, decrement outer loop...skip next line if ==0 goto Delay_0 ;1-ms has not expired, loop decfsz count1, f ;1-ms has expired, decrement master count by 1-ms, test, skip next if ==0 goto d1 ;Master count hasn't expired...loop and remove another millisecond. retlw 0x00 ;If master count ==0, exit subroutine because the count is up! ; Reset W register before RETURNing. end ;END OF PROGRAM