;********************************************
;***Title:Led Light Dimmer VERSION 2*********
;*Author:YC THAM*****************************
;**Date:12/6/2008****************************
;********************************************
ERRORLEVEL -302 ;remove message about using proper bank
#include <p12f629.inc>
__CONFIG _CP_OFF & _MCLRE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _CPD_OFF &_PWRTE_OFF
; __CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _WDT_ON & _PWRTE_ON & _BODEN_OFF & _CP_OFF & _CPD_OFF
ORIGINAL_PWM EQU H'0020'
COUNT50 EQU H'0021'
TEMP EQU H'0022'
A11 EQU H'0023'
A21 EQU H'0024'
GPIO EQU H'0005'
TRISIO EQU H'0085'
;******MAIN********
ORG 0x000
BCF STATUS,RP0; bank 0
CLRF GPIO; clear gpio
MOVLW 07h ; set to digital I/O
MOVWF CMCON ;
BSF STATUS,RP0 ; bank 1
CALL 3FFh; calibrate the internal oscillator
MOVWF OSCCAL;
MOVLW H'0038'; set the gp3,4,5 as input, gp0,1,2 as output
MOVWF TRISIO;
BCF STATUS,5;bank 0
BCF STATUS,C;clear carry flag
START
BTFSS GPIO,3 ; wait for On/OFF switch input
GOTO START; loop for input
CALL PREVIOUS ;restore previous saved PWM
GOTO INITIAL_PWM ;go to pwm output loop
INITIAL_PWM
MOVLW 0x38 ; set 0x38input
MOVWF GPIO ;
RESTART_PWM
MOVF ORIGINAL_PWM,w ; move original_pwm register data to w
MOVWF TEMP ;move w to temp register
BSF GPIO,0 ;turn on output gp0, cool white, HI
BTFSS GPIO,1 ;check for gp1 condition
CALL DELAY ;delay phase shift
BSF GPIO,1 ;turn on output gp1, warm white, HI
BTFSS GPIO,2 ;chec for gp2 condition
CALL DELAY ;delay phase shift
BSF GPIO,2 ;turn on output gp2, amber, HI
MOVLW d'255';test on the pwm condition
ADDWF ORIGINAL_PWM,0;prevent loop on 0 pwm
BTFSS STATUS,C;if pwm cycle >0 , loop for the cycles time
GOTO LOOP1;skip cycle count loop
BCF STATUS,C; clear carry flag
GOTO LOOP0;goto cycle count loop
LOOP0
DECFSZ TEMP,1 ;cycle count HI loop
GOTO LOOP0 ;
LOOP1
MOVLW d'255' ;total possible cycles, 255
MOVWF TEMP ;move to temp register for counter loop
MOVF ORIGINAL_PWM,w ;move original pwm to w for sub
SUBWF TEMP,1 ;sub temp with original pwm
BCF GPIO,0 ;turn gp0 to low
BTFSC GPIO,1 ;check for gp1 condition
CALL DELAY ;delay phase shift
BCF GPIO,1 ;turn gp1 to low
BTFSC GPIO,2 ;check for gp2 condition
CALL DELAY ;delay phase shift
BCF GPIO,2 ;turn gp2 to low
BCF STATUS,C ;clear carry flag
MOVLW d'255';test on pwm condition
ADDWF TEMP,0;prevent loop on 0 pwm
BTFSS STATUS,C;if pwm cycle >0 loop for cycles time
GOTO LOOP3;skip loop
LOOP2
DECFSZ TEMP,1 ;loop for cycle count
GOTO LOOP2 ;
LOOP3
BTFSS GPIO,3 ;check on switch on/off
GOTO START ;back to start if off, continue if on
BTFSC GPIO,4 ;check for the new pwm cycle changes
CALL SHAFT_0 ;increase/decrease on pwm cycle
GOTO RESTART_PWM ;continue loop for the current condition
;*********************************************
;** SUB-ROUTINE*******************************
;*********************************************
PREVIOUS:
BSF STATUS,5 ; bank1
MOVLW 0x10;eeprom address for saving data
MOVWF EEADR;go to address above 0x10
BSF EECON1,RD ;read data in address
MOVF EEDATA,w ;recall data to w register
BCF STATUS,5;bank0
MOVWF ORIGINAL_PWM;save to original_pwm register
RETURN
;****************************************
;**SAVE PWM IN EEPROM********************
;****************************************
SAVE_PWM:
BSF STATUS,5; bank 1
MOVLW 0x10;address to save data
MOVWF EEADR;go to addr 0x10
MOVF ORIGINAL_PWM,w ;move data on original_pwm to w
MOVWF EEDATA;send the data to eeprom
BSF EECON1,WREN ;write enable
BCF INTCON,GIE ;clear interrupt
MOVLW H'0055' ;<eeprom write sequence
MOVWF EECON2 ;<
MOVLW H'00AA' ;<
MOVWF EECON2 ;<
BSF EECON1,WR ;write in progress
LOOP_WR
BTFSC EECON1,WR; test for write process complete>?
GOTO LOOP_WR;if not complete loop till complete to ensure write successfully
BSF INTCON,GIE ;enable interrupt
BCF EECON1, WREN;disable write
BCF STATUS,5;bank 0
RETURN
;***************************************************
;****DELAY******************************************
;***************************************************
DELAY:
MOVLW d'50'; number of phase shifting loop
MOVWF COUNT50;
COUNT
DECFSZ COUNT50,1; loop for 50 cycles
GOTO COUNT;
RETURN
;**********************************************
;**DIRECTION***********************************
;**********************************************
SHAFT_0:
CLRF A11 ;clear A11 register
CLRF A21 ;clear A21 register
BCF STATUS,C;clear carry flag
BTFSC GPIO,4 ;check on gp4
GOTO SAVEBIT_A11 ;goto gp4=1 1st bit
GOTO SAVEBIT_A10 ;goto gp4=0
SHAFT_1
BTFSC GPIO,5 ;check on gp5
GOTO SAVEBIT_B11 ;goto gp5=1 2nd bit
GOTO SAVEBIT_B10 ;goto gp5=0
SHAFT_2
BTFSC GPIO,4 ;check on gp4
GOTO SAVEBIT_A21 ;goto gp4=1 3rd bit
GOTO SAVEBIT_A20 ;goto gp4=0
SHAFT_3
BTFSC GPIO,5 ;check on gp5
GOTO SAVEBIT_B21 ;goto gp5=1 4th bit
GOTO SAVEBIT_B20 ;goto gp5=0
SAVEBIT_A11
MOVLW b'00000001' ;gp4=1 1st bit =1
MOVWF A11 ;move to register A11
RLF A11,1 ;rotate left to make 4bit table check up!
GOTO SHAFT_1 ;back to 2nd bit check
SAVEBIT_A10
MOVLW b'00000000' ;gp4=0 1st bit =0
MOVWF A11 ;move to register A11
RLF A11,1 ;rotate left to make 4bit table check up
GOTO SHAFT_1 ;back to 2nd bit check
SAVEBIT_B11
MOVLW b'00000001' ;gp5=1 2nd bit =1
IORWF A11,1 ;inclusive or on A11 1st bit , result <00000011>/<00000001>
RLF A11,1 ;rotate left to make 4 bit table check up
RLF A11,1 ;rotate again to become 4bit
GOTO SHAFT_2 ;back to 3rd bit check
SAVEBIT_B10
MOVLW b'00000000' ;gp5=0 2rd bit =0
IORWF A11,1 ;inclusive or on A11 1stbit result <00000000>/<00000010>
RLF A11,1 ;rotate left to make 4 bit table check
RLF A11,1 ;rotate again to become 4bit
GOTO SHAFT_2 ;back to 3rd bit check
SAVEBIT_A21
MOVLW b'00000001' ;gp4=1 3rd bit =1
MOVWF A21 ;move to register A21
RLF A21,1 ;rotate left to make 4bit table check up
GOTO SHAFT_3 ;back to 4th bit check
SAVEBIT_A20
MOVLW b'00000000' ;gp4=0 3rd bit =0
MOVWF A21 ;move to register A21
RLF A21,1 ;rotate left again
GOTO SHAFT_3 ;back to 4th bit check
SAVEBIT_B21
MOVLW b'00000001' ;gp5=1 4th bit = 1
IORWF A21,0 ;inclusive or A21 3rd bit
IORWF A11,0 ;inclusive or with A11 to make up 4th bit
GOTO DIRECTION ; check on direction
SAVEBIT_B20
MOVLW b'00000000' ; gp5=1 4th bit =1
IORWF A21,0 ;inclusive or A21 3rd bit
IORWF A11,0 ;IOR with A11 to make up 4th bit
GOTO DIRECTION ;check for direction
DIRECTION
CALL TABLE_1 ;direction look up table
ANTI_CLOCKWISE
DECF ORIGINAL_PWM,f ; anti-clockwise means decrease on pwm cycle
MOVLW d'255'; to prevent decrease more than 0 cycle condition, turn to 255 cycle
SUBWF ORIGINAL_PWM,0; sub original_pwm
BTFSC STATUS,C; check on carry flag if cycle >0 , carry appears
GOTO RELOADZERO; if it is 0, reload zero to original_pwm register
GOTO NORMAL;if not, continue to save
RELOADZERO
MOVLW d'0'; load 0 to pwm due to over decrease happened
MOVWF ORIGINAL_PWM; move to register
BCF STATUS,C;clear carry flag
GOTO NORMAL;continue to save pwm
NORMAL
CALL SAVE_PWM ; call save pwm routine to save pwm data for recall on start up
GOTO RESTART_PWM ;return from save and continue to generate pwm signal
CLOCKWISE
MOVLW d'1'; clockwise means increase on pwm cycle
ADDWF ORIGINAL_PWM,0; add to the register to prevent over increment happned(more than 255)
BTFSC STATUS,C;it will turn to 0 cycle if over increment
GOTO RELOAD255; reload 255 cycle
INCF ORIGINAL_PWM,f ;increase pwm if no over increment condition happened
GOTO NORMAL;continue to save pwm
RELOAD255
MOVLW d'255'; load 255 to resigter due to over increment to 0 in w register
MOVWF ORIGINAL_PWM; move to resigter
GOTO NORMAL;continue to save pwm
RETURN
;************************************************
;**** DIRECTION TABLE****************************
;************************************************
TABLE_1:
ADDWF PCL,1 ; add the result to pc, result is from 4th bit generated
GOTO RESTART_PWM ; no increment nor decrement
GOTO ANTI_CLOCKWISE ; decrease on pwm
GOTO CLOCKWISE ;increase on pwm
GOTO RESTART_PWM ;
GOTO CLOCKWISE ;
GOTO RESTART_PWM ;
GOTO RESTART_PWM ;
GOTO ANTI_CLOCKWISE ;
GOTO ANTI_CLOCKWISE ;
GOTO RESTART_PWM ;
GOTO RESTART_PWM ;
GOTO CLOCKWISE ;
GOTO RESTART_PWM ;
GOTO CLOCKWISE ;
GOTO ANTI_CLOCKWISE ;
GOTO RESTART_PWM ;
RETURN
END