;************************************************* ;* 0002-01.ASM PIC12F683 Int 4MHz clock * ;* * ;* Instructable LED * ;* This is an LED, controlled by a PIC, that can * ;* be taught by flashing light at an LDR. * ;* Based on a design by Alex Weber * ;* * ;* Translation to PIC code * ;* (c)2007 Jonathan Clift * ;* * ;************************************************* ;* * ;************************************************* ;* Ver Date Who Change * ;* 01 22-04-07 JC * ;* * ;************************************************* ;* * ;* Configuration settings (for programming): * ;* Oscillator: INTRCIO * ;* Watchdog Timer: On * ;* Code Protect: All * ;* Master Clear: External * ;* * ;************************************************* ; ; General conventions: ; ; 1) RP0 and RP1 normally = 0 (bank 0) ; After accessing other banks, these page ; select bits are always reset. ; 2) IRP = 0. So, indirect addressing ; normally operates with banks 0 & 1 ; ; default radix will be decimal (so hex numbers ; must be preceded with 0x) ; radix dec ; LIST P=PIC12F683 INCLUDE "P12F683.INC" ; ;------------------------------------------------- ; ; Constants: ; ; GPIO bits ; LED EQU 5 ; ; flag bits for FLAGS register ; FSEC EQU 0 ;seconds flag FSAMP EQU 1 ;sample flag (10mS interval) FPROG EQU 2 ;programming FLAG3 EQU 3 ; FLAG4 EQU 4 ; FLAG5 EQU 5 ; ;-------------------------------------------------- ; ; Variables: ; ; page 0 ; ; general ; LOOPCNT EQU 0x20 ;loop counter PRESEC EQU 0x21 ;seconds prescaler TSTATE EQU 0x22 ;timer 1 state TEST EQU 0x23 FLAGS EQU 0x24 ;see above for bits ADVAL EQU 0x25 ;A/D value MSTATE EQU 0x26 ;main state MTEST EQU 0x27 VCOUNT EQU 0x28 VTEMP EQU 0x29 RTIMER EQU 0x2A ; ; learnt values go here ; VSTART EQU 0x30 ;start of data VEND EQU 0x70 ;end + 1 ; ; to save context during interrupts WTEMP EQU 0x70 WTEMP2 EQU 0xF0 STEMP EQU 0x71 PTEMP EQU 0x72 FTEMP EQU 0x73 ; ;************************************************* ;* Power up or watchdog entry point * ;* (fixed address - don't change) * ;************************************************* ; ORG 0x0000 GOTO INIT ; ;************************************************* ;* Interrupt routine * ;* Possible interrupt sources: * ;* - timer 0 * ;************************************************* ; ORG 0x0004 ; ; --- save state ; INT MOVWF WTEMP SWAPF STATUS,W CLRF STATUS MOVWF STEMP ; ; --- determine source of interrupt ; BTFSC PIR1,TMR1IF GOTO T1INT ;timer 0 interrupt ; ; --- restore state ; --- and return from interrupt ; IRETURN SWAPF STEMP,W MOVWF STATUS SWAPF WTEMP,F SWAPF WTEMP,W ; RETFIE ;return from interrupt ; ; --- handle timer 1 interrupt ; --- interrupts every 977uS ; --- (977uS x 256 x 4 = 1 sec) ; T1INT MOVLW 0x39 ;update timer MOVWF TMR1L ;(this sets the period) MOVLW 0xFC MOVWF TMR1H ; MOVF TSTATE,W MOVWF TEST ;copy to test ; ; --- state 1, signal sample time ; T1INT1 DECF TEST,F ;state = 1? BTFSS STATUS,Z GOTO T1INT2 ;no, jump ; BSF FLAGS,FSAMP ;set sample flag ; GOTO T1INT10 ; ; --- state 2, do background average ; T1INT2 DECF TEST,F ;state = 1? BTFSS STATUS,Z GOTO T1INT3 ;no, jump ; ; GOTO T1INT10 ; ; --- state 3, read A/D ; T1INT3 DECF TEST,F ;state = 2? BTFSS STATUS,Z GOTO T1INT4 ;no, jump ; MOVF ADRESH,W ;get result MOVWF ADVAL ;save ; GOTO T1INT10 ; ; --- state 4, start A/D ; T1INT4 DECF TEST,F ;state = 1? BTFSS STATUS,Z GOTO T1INT10 ;no, jump ; BSF ADCON0,1 ;start conversion ; GOTO T1INT10 ; ; --- update state, etc ; T1INT10 DECF TSTATE,F ;decrement state BTFSS STATUS,Z ;down to zero? GOTO T1INT30 ; MOVLW 20 ;yes, reset to 10 MOVWF TSTATE ; T1INT30 BCF PIR1,TMR1IF ;reset timer 1 interrupt bit GOTO IRETURN ; ;************************************************* ;* Initialisation code for start up * ;* falls into main routine * ;************************************************* ; INIT ; ; --- set initial i/o direction ; --- GP0 is an analogue input ; --- GP2 and GP5 are digital outputs ; BCF STATUS,RP0 BCF STATUS,RP1 BCF STATUS,IRP MOVLW 0x24 MOVWF GPIO MOVLW 0x07 ;comparator off MOVWF CMCON0 BSF STATUS,RP0 MOVLW 0x51 MOVWF ANSEL MOVLW 0x1B MOVWF TRISIO BCF STATUS,RP0 ; CLRWDT ; ; --- initialise value memory ; MOVLW 16 MOVWF VCOUNT MOVLW VSTART ;set start address MOVWF FSR INIT1 MOVLW 0xFF MOVWF INDF INCF FSR,F MOVWF INDF INCF FSR,F MOVLW 0x00 MOVWF INDF INCF FSR,F MOVWF INDF INCF FSR,F DECF VCOUNT,F BTFSS STATUS,Z GOTO INIT1 ; ; --- initialise variables ; MOVLW 20 MOVWF TSTATE MOVLW 1 ;next state 1 MOVWF MSTATE MOVLW VSTART ;set start address MOVWF FSR MOVLW 8 ;set bit count MOVWF VCOUNT MOVF INDF,W MOVWF VTEMP ; ; --- set up A/D convertor ; MOVLW 0x01 ;turn on A/D MOVWF ADCON0 ; ; --- set up timer 1 ; MOVLW 0x39 ;set timer MOVWF TMR1L MOVLW 0xFC MOVWF TMR1H BCF PIR1,TMR1IF ;reset timer 1 interrupt bit MOVLW 0x01 ;sets timer to be on MOVWF T1CON BSF STATUS,RP0 BSF PIE1,TMR1IE ;enable interrupt BCF STATUS,RP0 ; ; --- enable interrupts ; MOVLW 0xC0 ;enable interrupts MOVWF INTCON ;in control reg ; ;************************************************* ;* Main routine * ;* * ;************************************************* ; ; --- main processing loop ; MAIN CLRWDT ; ; --- is sample flag set? ; BTFSS FLAGS,FSAMP GOTO MAIN ; MOVF MSTATE,W ;get main state MOVWF MTEST ;copy to test ; ; --- state 1, REPLAY ; MAIN10 DECF MTEST,F ;state = 1? BTFSS STATUS,Z GOTO MAIN20 ;no, jump ; DECF VCOUNT,F BTFSS STATUS,Z GOTO MAIN11 ; MOVLW 8 MOVWF VCOUNT INCF FSR,F ; MOVLW VEND SUBWF FSR,W BTFSS STATUS,Z GOTO MAIN14 MOVLW VSTART MOVWF FSR ; MAIN14 MOVF INDF,W MOVWF VTEMP ; MAIN11 BCF STATUS,C RLF VTEMP,F BTFSS STATUS,C GOTO MAIN12 BCF GPIO,LED ;LED off GOTO MAIN13 MAIN12 BSF GPIO,LED ;LED on ; MAIN13 MOVF ADVAL,W SUBLW 20 BTFSS STATUS,C GOTO MAIN90 ; MOVLW 2 MOVWF MSTATE MOVLW 50 MOVWF RTIMER ; GOTO MAIN90 ; ; --- state 2, READY ; MAIN20 DECF MTEST,F ;state = 2? BTFSS STATUS,Z GOTO MAIN30 ;no, jump ; BSF GPIO,LED ;LED on DECF RTIMER,F ;timer done? BTFSS STATUS,Z GOTO MAIN90 ;no, finish ; BCF GPIO,LED ;yes, LED off MOVLW 3 ;next state 3 MOVWF MSTATE MOVLW VSTART ;set start address MOVWF FSR MOVLW 8 ;set bit count MOVWF VCOUNT ; GOTO MAIN90 ; ; --- state 3, READ AND STORE ; MAIN30 DECF MTEST,F ;state = 3? BTFSS STATUS,Z GOTO MAIN40 ;no, jump ; MOVF ADVAL,W SUBLW 20 BTFSS STATUS,C GOTO MAIN31 ; BCF GPIO,LED ;LED off GOTO MAIN32 ; MAIN31 BSF GPIO,LED ;LED on ; MAIN32 RLF VTEMP,F DECF VCOUNT,F BTFSS STATUS,Z GOTO MAIN90 ; MOVLW 8 MOVWF VCOUNT MOVF VTEMP,W MOVWF INDF INCF FSR,F MOVLW VEND SUBWF FSR,W BTFSS STATUS,Z GOTO MAIN90 ; MOVLW VSTART MOVWF FSR MOVLW 4 MOVWF MSTATE MOVLW 50 MOVWF RTIMER ; GOTO MAIN90 ; ; --- state 4, DONE ; MAIN40 DECF MTEST,F ;state = 4? BTFSS STATUS,Z GOTO MAIN90 ;no, jump ; BSF GPIO,LED ;LED on DECF RTIMER,F ;timer done? BTFSS STATUS,Z GOTO MAIN90 ;no, finish ; BCF GPIO,LED ;yes, LED off MOVLW 1 ;next state 1 MOVWF MSTATE MOVLW VSTART ;set start address MOVWF FSR MOVLW 8 ;set bit count MOVWF VCOUNT MOVF INDF,W MOVWF VTEMP ; GOTO MAIN90 ; ; --- common end stuff ; MAIN90 BCF FLAGS,FSAMP GOTO MAIN ; END