list p=16F84 ; list directive to define processor #include ; processor specific variable definitions ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ;***** VARIABLE DEFINITIONS w_temp EQU 0x0C ; variable used for context saving status_temp EQU 0x0D ; variable used for context saving counter EQU 0x0E ; a counter flags EQU 0x0F ; various flags counter1 EQU 0x10 ; little counter; pwmg EQU 0x11 ; greens pwm value (0..255) pwmb EQU 0x12 ; blues pwm value (0..255) dispdat EQU 0x13 ; what is on the grade digit grade EQU 0x14 ; grade from display ;***** CONSTANTS inthap EQU 0 ; interrupt happened flag gout EQU 1 ; port a green output bout EQU 0 ; port a blue output safe EQU 3 ; safelight on input active low lamp EQU 4 ; enlarger lamp input active low spare EQU 2 ; spare i/o pulled up 2k2 ;********************************************************************** ORG 0x000 ; processor reset vector goto main ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; 1 save current W register contents movf STATUS,w ; 1 move status register into W register movwf status_temp ; 1 save contents of STATUS register bcf STATUS, RP0 ; 1 bank 0 movlw .200 ; 1 256 - number of cycles between interrupts (56) movwf TMR0 ; 1 set counter bcf flags, inthap ; 1 flag a run through interrupt incf counter, F ; 1 up! movfw pwmg ; 1 get pwm for green addwf counter, W ; 1 add counter bcf PORTA, gout ; 1 clear pwm output btfsc STATUS, C ; 2 test carry bsf PORTA, gout ; 1 if overflow set output movfw pwmb ; 1 get pwm for blue addwf counter, W ; 1 add counter bcf PORTA, bout ; 1 clear pwm output btfsc STATUS, C ; 2 test carry bsf PORTA, bout ; 1 if overflow set output bcf INTCON, 2 ; 1 re-enable interrupt movf status_temp,w ; 1 retrieve copy of STATUS register movwf STATUS ; 1 restore pre-isr STATUS register contents swapf w_temp,f ; 1 restore status swapf w_temp,w ; 1 restore pre-isr W register contents retfie ; 1 return from interrupt ; total of 27 cycles max plus interrupt overheads 4 31 cycles total 56 will be enough ; no prescalar on timer 4MHz clock, 71Hz pwm frequency ; routine takes 31us, mpx much less than this main bcf STATUS, RP0 ; bank 0 movlw B'10100000' ; enable timer overflow interrupt movwf INTCON ; do it movlw B'10001111' ; tmr0 from int clk no prescalar, wdt 256 prescalar OPTION ; do it movlw B'11111111' ; port b TRIS PORTB ; all inputs movlw B'00011100' ; port a TRIS PORTA ; 0, 1 outputs clrf PORTA ; all zero ; lamp turns on the leds by hardware, so.... start call getgrade ; get display call expose ; fill pwm with current grade btfsc PORTA, safe ; test safe goto start ; off, try again call getgrade ; use as a delay btfsc PORTA, lamp ; lamp as well? goto start ; no, try again ; if both on then in focus mode, next mode could be measure, this turns off safe only. brightbit call getgrade ; grade might have changed call fullon ; max light btfss PORTA, lamp ; lamp off yet goto brightbit ; it' not ; so wait until lamp is off. goto start ; done ; get grade from display, if a grade put in grade number getgrade call getdisp ; grade might have changed btfsc W, 7 ; valid grade movwf grade ; store it return ; exposure levels expose movfw grade ; get grade call gpwm ; lut movwf pwmg ; set movfw grade ; get grade call bpwm ; lut movwf pwmb ; set return ; full on levels fullon movlw .255 ; maximum movwf pwmg ; green full movwf pwmb ; blue full return ; return 0..10 in W for grades, sets bit 4 for "P", bit 5 for "B" bit 6 for "t" and bit 7 of not a grade ; segments a, b, c, d, e, g and dp needed RB 0..6, mpx on 7 getdisp bcf flags, inthap ; clear interrupt happened flag clrwdt ; reset wdt btfss PORTB, 7 ; wait for goto getdisp ; multiplex movfw PORTB ; display clrwdt ; reset wdt btfss PORTB, 7 ; check if still up goto getdisp ; oops don't use that reading clrwdt ; reset wdt btfss flags, inthap ; test if interrrupt happened goto getdisp ; and try again andlw B'01111111' ; dump junk movwf dispdat ; to file movlw B'01100011' ; o subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .1 ; return grade number movlw B'00100011' ; o. subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .2 ; return grade number movlw B'01100000' ; 0 subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .3 ; return grade number movlw B'00100000' ; 0. subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .4 ; return grade number movlw B'01111001' ; 1 subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .5 ; return grade number movlw B'00111001' ; 1. subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .6 ; return grade number movlw B'01000100' ; 2 subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .7 ; return grade number movlw B'00000100' ; 2. subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .8 ; return grade number movlw B'01010000' ; 3 subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .9 ; return grade number movlw B'00010000' ; 3. subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .10 ; return grade number movlw B'01011001' ; 4 subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .11 ; return grade number movlw B'00011001' ; 4. subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .12 ; return grade number movlw B'01010010' ; 5 subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw .13 ; return grade number movlw B'01000111' ; t subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw B'11000000' ; 7 no grade 6 't' movlw B'01000000' ; B subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw B'10100000' ; 7 no grade 5 'B' movlw B'01001100' ; P subwf dispdat, W ; test btfsc STATUS, Z ; if zero, must be the one retlw B'10010000' ; 7 no grade 4 'P' retlw B'10000000' ; none of the above ; Grade 00, 00.5 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5 gpwm addwf PCL, F ; 1 first location retlw .255 ; 0, never happens(!) to shift lut entry retlw .255 retlw .226 retlw .194 retlw .167 retlw .142 retlw .117 retlw .96 retlw .76 retlw .57 retlw .40 retlw .25 retlw .11 retlw .0 ; Grade 00, 0, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5 bpwm addwf PCL, F ; 0 first location retlw .255 ; 0, never happens(!) to shift lut entry retlw .0 retlw .20 retlw .40 retlw .56 retlw .70 retlw .85 retlw .96 retlw .105 retlw .115 retlw .121 retlw .123 retlw .127 retlw .128 END ; directive 'end of program'