;********************************************************************** ; * ; Filename: 3led.asm * ; Date: * ; File Version: * ; * ; Author: * ; Company: * ; * ; * ;********************************************************************** ; * ; Files required: * ; * ; * ; * ;********************************************************************** ; * ; Notes: * ; 06.6.13 Ver 1.0 * ; * ; * ; * ;********************************************************************** list p=12f675 ; list directive to define processor #include ; processor specific variable definitions errorlevel -302 ; suppress message 302 from list file __CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT ; '__CONFIG' directive is used to embed configuration word within .asm file. ; The lables following the directive are located in the respective .inc file. ; See data sheet for additional information on configuration word settings. LED_A EQU GP2 ;red LED_B EQU GP4 ;green LED_C EQU GP5 ;blue ;***** VARIABLE DEFINITIONS w_temp EQU 0x20 ; variable used for context saving status_temp EQU 0x21 ; variable used for context saving TimeA EQU 0x22 TimeB EQU 0x23 TimeC EQU 0x24 SetTimeA EQU 0x25 ;red high sound SetTimeB EQU 0x26 ;green low sound SetTimeC EQU 0x27 ;blue BrightA EQU 0x28 BrightB EQU 0x29 BrightC EQU 0x2a inc_phase EQU 0x2b divider EQU 0x2c z_count EQU 0x2d ee_pointer EQU 0x2e ; ;use like auto variable ; _w EQU 0x5b _n EQU 0x5c _a EQU 0x5d _b EQU 0x5e _c EQU 0x5f ;********************************************************************** ORG 0x000 ; processor reset vector goto main ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register ; isr code can go here or be located as a call subroutine elsewhere movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt ; these first 4 instructions are not required if the internal oscillator is not used main call 0x3FF ; retrieve factory calibration value bsf STATUS,RP0 ; set file register bank to 1 movwf OSCCAL ; update register with factory cal value ;;; bcf STATUS,RP0 ; set file register bank to 0 clrf INTCON clrwdt movlw b'11011011' ;WDT select,1/8(typ. 144msec) movwf OPTION_REG clrwdt movlw h'20' ;file registers clear movwf FSR movlw h'3f' ;clear 20h to 5Fh fregclr clrf INDF incf FSR,f addlw h'ff' ;w-- btfss STATUS,Z goto fregclr movlw b'00001011' movwf TRISIO movlw b'01010011' ;Fosc/16, AN1 & AN0 are analog input movwf ANSEL bcf STATUS,RP0 ;bank 0 movlw b'10000011' ;format 1, ref=VDD movwf ADCON0 movlw 0 ;read from EEADR 0 movwf _a movlw ee_pointer ;to ee_pointer movwf _b movlw 1 ;1 byte movwf _c call readEE movf ee_pointer,w ;get EEADR addwf ee_pointer,w addwf ee_pointer,w addlw 1 movwf _a ;_a = 3*pointer + 1 movlw BrightA movwf _b movlw 3 movwf _c ;3 byte call readEE incf ee_pointer,f ;new pointer set movlw .40 subwf ee_pointer,w btfsc STATUS,Z clrf ee_pointer movlw ee_pointer ;write ee_pointer movwf _a movlw 0 movwf _b movlw 1 movwf _c call writeEE movf BrightA,w call exp_conv movwf SetTimeA movf BrightB,w call exp_conv movwf SetTimeB movf BrightC,w call exp_conv movwf SetTimeC movlw .80 movwf _n init_loop clrwdt incf divider,f movlw .64 subwf divider,w ;w = divider - 64 btfss STATUS,Z goto init_out clrf divider decfsz _n,f goto init_out movf ADRESH,w ;dummy read bsf STATUS,RP0 ;bank 1 movf ADRESL,w bcf STATUS,RP0 ;bank 0 clrf BrightA clrf SetTimeA clrf BrightB clrf SetTimeB clrf BrightC clrf SetTimeC goto loop init_out movlw .10 call wait_loop call PWMout goto init_loop loop clrwdt incf divider,f movlw .64 subwf divider,w ;w = divider - 64 btfss STATUS,Z goto led_control clrf divider ;if Z, clear divider movf BrightC,w call exp_conv movwf SetTimeC movf inc_phase,w btfss STATUS,Z goto inc_check movf BrightC,w ;if ZERO, dec phase btfss STATUS,Z goto dec_cycle movlw 1 ;if ZERO, end of dec phase movwf inc_phase goto inc_cycle inc_check movlw .255 ;inc limit check subwf BrightC,w btfss STATUS,Z goto inc_cycle clrf inc_phase ;end of inc phase goto dec_cycle inc_cycle incf BrightC,f goto color_set dec_cycle decf BrightC,f color_set bsf STATUS,RP0 ;bank 1 btfss BrightC,0 goto color_a movf ADRESL,w ;w = AD result btfsc STATUS,Z goto fade_b addwf BrightB,w ;if any input, inc bright btfsc STATUS,C movlw .255 movwf BrightB goto exp_set_b fade_b ;;; incf _b,f ;if Z, dec bright ;;; movlw .3 ;;; andwf _b,w ;;; btfss STATUS,Z ;;; goto is_signal movf BrightB,w btfsc STATUS,Z goto is_signal ;;; decf BrightB,f call exp_dec movwf BrightB exp_set_b movf BrightB,w call exp_conv movwf SetTimeB goto is_signal color_a movf ADRESL,w ;w = AD result btfsc STATUS,Z goto fade_a addwf BrightA,w ;if any input, inc bright btfsc STATUS,C movlw .255 movwf BrightA goto exp_set_a fade_a ;;; incf _a,f ; ;if Z, dec bright ;;; movlw .1 ;;; andwf _a,w ;;; btfss STATUS,Z ;;; goto is_signal movf BrightA,w btfsc STATUS,Z goto is_signal ;;; decf BrightA,f call exp_dec movwf BrightA exp_set_a movf BrightA,w call exp_conv movwf SetTimeA is_signal bcf STATUS,RP0 ;bank 0 movf SetTimeA,f btfss STATUS,Z goto ad_begin movf SetTimeB,f btfss STATUS,Z goto ad_begin incf z_count,f movlw .50 subwf z_count,w btfss STATUS,Z goto adb10 good_night bcf ADCON0,0 ;reset ADON movlw b'00110100' movwf GPIO ;LED off clrwdt sleep bsf ADCON0,0 ;omajinai on wakeup movlw .1 ;omajinai call wait_loop ;omajinai movlw .16 movwf z_count z_check movlw b'10000011' ;ch 0 --- high movwf ADCON0 movlw .75 call wait_loop bsf STATUS,RP0 ;bank 1 movf ADRESL,f bcf STATUS,RP0 ;bank 0 btfss STATUS,Z goto ad_begin movlw b'10000011' ;ch 0 --- high movwf ADCON0 movlw .75 call wait_loop bsf STATUS,RP0 ;bank 1 movf ADRESL,f bcf STATUS,RP0 ;bank 0 btfss STATUS,Z goto ad_begin decfsz z_count,f goto z_check goto good_night ad_begin clrf z_count adb10 btfss BrightC,0 goto start_ch0 movlw b'10000111' ;ch 1 goto adcon_set start_ch0 movlw b'10000011' ;ch 0 adcon_set movwf ADCON0 led_control movlw .10 call wait_loop call PWMout goto loop ; ;Pulse Width Modulation output ; PWMout movf TimeA,w btfss STATUS,Z ;zero check goto NextA ;if not zero, count down btfss GPIO,LED_A ;ON or OFF? goto BeginA bcf GPIO,LED_A ;begining of ON movf SetTimeA,w movwf TimeA goto CheckB BeginA bsf GPIO,LED_A ;begining of OFF movf SetTimeA,w xorlw 0xff movwf TimeA goto CheckB NextA decf TimeA,f CheckB movf TimeB,w btfss STATUS,Z ;zero check goto NextB ;if not zero, count down btfss GPIO,LED_B ;ON or OFF? goto BeginB bcf GPIO,LED_B ;begining of ON movf SetTimeB,w movwf TimeB goto CheckC BeginB bsf GPIO,LED_B ;begining of OFF movf SetTimeB,w xorlw 0xff movwf TimeB goto CheckC NextB decf TimeB,f CheckC movf TimeC,w btfss STATUS,Z ;zero check goto NextC ;if not zero, count down btfss GPIO,LED_C ;ON or OFF? goto BeginC bcf GPIO,LED_C ;begining of ON movf SetTimeC,w movwf TimeC goto PWMEnd BeginC bsf GPIO,LED_C ;begining of OFF movf SetTimeC,w xorlw 0xff movwf TimeC goto PWMEnd NextC decf TimeC,f PWMEnd return ; ;about 4*w_count usec delay ; wait_loop movwf _w w10 clrwdt ;1 Tcy decfsz _w,f ;1(2) Tcy goto w10 ;2 Tcy return ;2 Tcy ; ;exponential convertion ; exp_conv movwf _w sublw .128 btfss STATUS,C goto ex10 rrf _w,f ;under 128, /= 4 rrf _w,f movlw h'3f' andwf _w,w ;w = w/4 goto exx ex10 movf _w,w ;128 to 191 sublw .192 btfss STATUS,C goto ex20 movlw .96 subwf _w,w ;w = (f) - w goto exx ;w = w - 96 ex20 movlw .192 ;upper 192 subwf _w,f ;_w = _w - 192 rlf _w,f movlw .96 addwf _w,w ;w = 2*(w - 192) + 96 exx return ; ;decrement value set exponentially ; exp_dec movwf _w sublw .128 btfss STATUS,C goto exd10 movlw 1 ;under 128,dec 1 goto exdend exd10 movf _w,w ;128 to 191 sublw .192 btfss STATUS,C goto exd20 movlw 2 goto exdend exd20 movlw 4 ;upper 192 exdend subwf _w,w ;w = _w - w return ; ;char getEE(char w) ;return data into w ;Caution! use on bank 1 ; getEE movwf EEADR bsf EECON1,RD movf EEDATA,w return ; ;void putEE ;Caution! use on bank 1 ;use _n ; putEE ;;; btfsc EECON1,WR ;check write enable ;;; goto putEE ;not used 03.12.20 movlw h'55' movwf EECON2 movlw h'aa' movwf EECON2 bsf EECON1,WR movlw .7 ;wait 7msec movwf _n ee_wait movlw .250 call wait_loop decfsz _n,f goto ee_wait return ; ;void readEE(char *_a, char *_b, unsigned char _c) ;/* read EEPROM from _a, store to _b, _c bytes */ ; readEE bsf STATUS,RP0 ;bank 1 movf _b,w movwf FSR rd10 movf _a,w call getEE movwf INDF incf _a,f incf FSR,f decfsz _c,f goto rd10 bcf STATUS,RP0 ;bank 0 return ; ;char writeEE(char *_a, char *_b, unsigned char _c) ;/* read from _a, write EEPROM to _b, _c bytes */ ;/* return 1 if OK else 0 */ ; writeEE bsf STATUS,RP0 ;bank 1 bsf EECON1,WREN movf _a,w movwf FSR wr10 movf _b,w ;dest movwf EEADR movf INDF,w movwf EEDATA call putEE movf EEDATA,w bsf EECON1,RD ;verfy 04.9.28 xorwf EEDATA,w btfss STATUS,Z goto write_err incf FSR,f incf _b,f decfsz _c,f goto wr10 bcf EECON1,WREN bcf STATUS,RP0 ;bank 0 movlw .1 goto wrex write_err clrw wrex return ; ; initialize eeprom locations ; ORG 0x2100 DE 0x00 ;pointer DE .250,.65,.47 DE .38,.121,.33 DE .233,.123,.175 DE .202,.77,.46 DE .147,.204,.214 DE .80,.135,.80 DE .167,.95,.222 DE .169,.169,.239 DE .248,.175,.38 DE .174,.33,.124 DE .143,.208,.80 DE .168,.246,.100 DE .162,.94,.119 DE .224,.133,.231 DE .198,.247,.147 DE .220,.136,.78 DE .117,.69,.21 DE .233,.199,.206 DE .71,.102,.173 DE .43,.56,.163 DE .199,.245,.126 DE .212,.198,.29 DE .166,.112,.50 DE .245,.240,.121 DE .11,.224,.196 DE .211,.39,.149 DE .146,.183,.70 DE .195,.4,.34 DE .89,.244,.250 DE .134,.43,.133 DE .79,.47,.69 DE .208,.155,.10 DE .117,.108,.7 DE .22,.230,.46 DE .120,.50,.18 DE .11,.37,.92 DE .48,.172,.154 DE .200,.253,.107 DE .101,.39,.136 DE .251,.87,.22 END ; directive 'end of program'