; ; Technical Aid to the Disabled, Australia ; Custom-Designed Aids Service, Sydney ; Project No. 98/552 98/553 ; Client Lee-Anne Sturgess ; ; Program for PIC 12C509A microcontroller for light box switching ; Written by James Cameron ; Revision BX1 13-Sep-1998 ; proto equ 0 ; we are prototyping on 16F84 ; change to zero for final burn if proto == 1 processor 16f84 list f=inhx8m include "p16f84.inc" __CONFIG _CP_OFF & _WDT_OFF & _HS_OSC else processor 12c509 list f=inhx8m include "p12c509a.inc" __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC endif ; general purpose register allocation ; first common free address as per ; p12 of 12c509 spec ; p13 of 16f84 spec tmp1 equ 0x0c ; delay loop outer counter tmp2 equ 0x0d ; delay loop inner counter a_left equ 0x12 ; duty cycle accumulators a_right equ 0x13 d_left equ 0x14 ; duty cycle settings d_right equ 0x15 a_heat1 equ 0x16 ; heat accumulators a_heat2 equ 0x17 ; heat reset value k_heat equ d'72' ; seconds / 2.56 (default 70, 180s) ; duty cycles, modulus 256 k_warm equ d'4' ; warming (ax3; 3 had no glow, 5 glowed overly) k_on equ d'200' ; light on ; interface bit definitions if proto == 1 ; which port to use port equ PORTA else port equ GPIO endif b_left equ 0x00 ; gate of mosfet for left lamp b_right equ 0x01 ; gate of mosfet for right lamp b_led equ 0x02 ; red diagnostic led via 1k res b_go equ 0x03 ; inverted pushbutton with 0.01uF cap org 0x00 ; reset vector if proto != 1 movwf OSCCAL ; store oscillator calibration endif goto main dt "james.cameron@digital.com rev bx1 1998-09-13" cool ; reset heat counter clrw movwf a_heat1 ; reset LSB movlw k_heat movwf a_heat2 ; reset MSB retlw 0 heat ; called every 10ms movlw k_on subwf d_left,w ; set zero flag if lamp on btfsc STATUS,Z ; skip if not zero goto heat_2 ; jump if it is on movlw k_on subwf d_right,w ; set zero flag if lamp on btfsc STATUS,Z ; check right lamp goto heat_2 ; jump if it is on heat_1 retlw 0 ; neither on, return heat_2 decf a_heat1,f ; decrement the heat counter LSB btfss STATUS,Z ; skip if zero goto heat_1 ; jump if not zero decf a_heat2,f ; decrement the heat counter MSB btfss STATUS,Z ; skip if zero goto heat_1 ; jump if no overflow (Z=0) goto main ; overheat; bug out! light ; update lights using duty cycles movf d_left,w addwf a_left,f btfsc STATUS,C goto light_1 bcf port,b_left goto light_2 light_1 bsf port,b_left light_2 movf d_right,w addwf a_right,f btfsc STATUS,C goto light_3 bcf port,b_right goto light_4 light_3 bsf port,b_right light_4 ; timing; 12 to 14 cycles per pass retlw 0 ms macro delay ; delay "w" number of milliseconds local ms_0, ms_1 movlw delay ; set argument movwf tmp1 ; copy argument ms_0 ; start of 1mS loop movlw d'48' ; (tailored in ax2 for 1ms based on light call) movwf tmp2 ; move to register bank ms_1 call light ; keep lights on during delay decfsz tmp2,f ; decrement inner counter goto ms_1 ; end of loop decfsz tmp1,f ; decrement outer (1mS) counter goto ms_0 ; end of 1mS loop endm button ; wait for a button press event ms d'100' ; delay for debounce on button press button_0 ms d'10' ; heat time base call heat ; abort on overheat call light ; keep lights on during wait btfss port,b_go ; wait for button to be released goto button_0 ; still zero, contact closed, loop ms d'10' ; small delay for debounce btfss port,b_go ; still released after delay? goto button_0 ; no, so loop bcf port,b_led ; turn led off ; contact has opened (or was open) ms d'100' ; delay for debounce on button release button_1 ms d'10' ; heat time base call heat ; abort on overheat call light ; keep lights on during wait btfsc port,b_go ; wait for button to be pressed goto button_1 ms d'10' ; small delay for debounce btfsc port,b_go ; contact still closed after delay? goto button_1 bsf port,b_led ; turn led on ; contact has closed retlw 0 main movf a_left,w ; set lamps 180 degrees out of phase xorlw 0x80 movwf a_right loop ; [re-]initialise i/o registers ; repeated in case of EMC movlw b'001000' ; gp0 gp1 gp2 gp4 gp5 out, gp3 in if proto == 1 ; are we on 16f84? bsf STATUS,RP0 ; select register bank 1 movwf TRISA ; set port a direction register bcf STATUS,RP0 ; select register bank 0 else ; otherwise 12c509 tris GPIO ; set port direction register bcf OPTION,TOCS ; we want GP2 as output (note p15 spec) endif movlw k_warm ; turn lamps down to warming level movwf d_left movwf d_right call cool ; reset heat countdown call button ; wait for button press movlw k_on ; turn left lamp up movwf d_left call cool ; reset heat countdown call button ; wait for button press movlw k_warm ; turn left lamp down movwf d_left movlw k_on ; turn right lamp up movwf d_right call cool ; reset heat countdown call button ; wait for button press goto loop ; loop for another cycle end