;********************************************************************** ; This file is a basic code template for assembly code generation * ; on the PICmicro PIC12C508. This file contains the basic code * ; building blocks to build upon. * ; * ; If the internal RC oscillator is not implemented then the first * ; instruction after the ORG 0x000 directive is not required. * ; * ; Refer to the MPASM User's Guide for additional information on * ; features of the assembler (Document DS33014). * ; * ; Refer to the respective PICmicro data sheet for additional * ; information on the instruction set. * ; * ; Template file assembled with MPASM V2.11.01 * ; * ;********************************************************************** ; * ; Filename: door.asm * ; Date: * ; File Version: * ; * ; Author: el@jap.hu * ; Company: http://jap.hu/electronic/ * ; * ; * ;********************************************************************** ; * ; Files required: * ; * ; * ; * ;********************************************************************** ; * ; Notes: * ; * ; * ; * ; * ;********************************************************************** ;#3; veglegesnek szant valtozat, setup moddal ;digitek: doortime XX; delaytime XX hexa, tizedmasodpercben ;#define F84 #define C508 #ifdef C508 list p=12c508 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _MCLRE_OFF & _IntRC_OSC ; '__CONFIG' directive is used to embed configuration word 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. #endif #ifdef F84 list p=16F84 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ; '__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. #endif ;***** VARIABLE DEFINITIONS #ifdef C508 freemem EQU 0x07 #endif #ifdef F84 freemem EQU 0x10;0x0c #endif temp EQU freemem+0x00 button EQU freemem+0x01 prevbut EQU freemem+0x02 btcnt EQU freemem+0x03 ;button counter doorcnt EQU freemem+0x04 ;relay ON counter delaycnt EQU freemem+0x05 ;delay before door open counter dlcnt0 EQU freemem+0x06 ;delay sub counter 0 dlcnt1 EQU freemem+0x07 ;delay sub counter 1 ringer EQU freemem+0x08 prevring EQU freemem+0x09 ringcnt EQU freemem+0x0a switch EQU freemem+0x0b ledcnt EQU freemem+0x0c iobuf EQU freemem+0x0d ;IOPORT buffer ledpwm EQU freemem+0x0e ledstate1 EQU freemem+0x0f ledstate2 EQU freemem+0x10 ledtemp1 EQU freemem+0x11 ledtemp2 EQU freemem+0x12 flashdir EQU freemem+0x13 ;flash direction doortime EQU freemem+0x14 ;door open time delaytime EQU freemem+0x15 ;delay time prevsw EQU freemem+0x16 ;previous state of switch ;***** I/O structure ;my F84 testpanel properties ; ;RB0 testled DB25/16 OUT ;RB1 testled DB25/4 OUT ;RB2 testled ;RB3 DB25/15 IN ;RA2 serial OUT ;RA4 DB25/13 ;GP0 O RED LED ;GP1 I BUTTON ;GP2 O GREEN LED ;GP3 I SWITCH ;GP4 I RINGER ;GP5 O RELAY CTL #ifdef C508 IOPORT EQU GPIO #endif #ifdef F84 IOPORT EQU PORTB #endif #ifdef C508 ;********************************************************************** ORG 0x1FF ; processor reset vector ; Internal RC calibration value is placed at location 0x1FF by Microchip ; as a movlw kk, where the kk is a literal value. ORG 0x000 ; coding begins here movwf OSCCAL ; update register with factory cal value clrf GPIO movlw 0x1a tris GPIO ;GP4, GP3, GP1 input movlw 0x80 option ;wakeup DIS, pullup EN ;take care of other internal hardware here ; remaining code goes here #endif #ifdef F84 clrf PORTB clrf PORTA movlw 0x1a tris PORTB movlw 0xff tris PORTA ;not used movlw 0 ;pullup EN option #endif LED_GRN EQU 0x31 LED_YEL EQU 0x18 LED_RED EQU 0x00 cold movlw .30 movwf doortime movlw .200 movwf delaytime warm ;reset test ;green led ON clrf iobuf movlw 4 movwf ledstate1 movlw 1 movwf ledstate2 movlw LED_RED movwf ledpwm movlw 5 movwf temp test0 call delay decfsz temp goto test0 ;green+red led ON movlw LED_YEL ;YEL movwf ledpwm movlw 5 movwf temp test1 call delay decfsz temp goto test1 clrf IOPORT ;reset test end ;init variables clrf btcnt clrf doorcnt clrf delaycnt clrf ringcnt clrf button clrf ringer movlw 5 movwf flashdir ;main cycle cycle call delay clrf iobuf movf button,W movwf prevbut movf IOPORT,W andlw 2 movwf button ;store button status movf ringer,W movwf prevring movf IOPORT,W andlw 0x10 movwf ringer ;store ringer status movf IOPORT,W andlw 8 ;auto switch status movwf switch call button_sub call door_sub btfsc switch,3 ;no ringercheck if switch is OFF call ringer_sub call led_sub movf iobuf,W movwf IOPORT call setup_sub ;optional setup for timers goto cycle delay movf iobuf,W iorwf ledstate1,W movwf ledtemp1 movf iobuf,W iorwf ledstate2,W movwf ledtemp2 movlw .250 movwf dlcnt1 delay1 movlw 0x30 movwf dlcnt0 delay2 movf ledpwm,W subwf dlcnt0,W movf ledtemp1,W btfsc STATUS, C movf ledtemp2,W movwf IOPORT decfsz dlcnt0 goto delay2 decfsz dlcnt1 goto delay1 bcf IOPORT, 2 retlw 0 button_sub movf button,W xorwf prevbut,W bz bt_unchanged ;button status changed btfss button,1 ;test button status goto bt_release ;button release ; ;button pressed, reset counter clrf btcnt ; bt_unchanged btfsc button,1 ;test button status incf btcnt ;measure pressing time ; retlw 0 ; bt_release ;if the button is just released ; movlw 5 subwf btcnt,W ;check pressing time ; clrf btcnt bc bt_long ; ;less than half second, immediate ON relay ;but only if not already in progress movf doorcnt,W bnz bt_skip clrf delaycnt ;clear delays movf doortime,W movwf doorcnt ;set relay ON time ; bsf iobuf, 5 bt_skip retlw 0 bt_long movf delaytime,W ;set delay time movwf delaycnt retlw 0 door_sub ;delay movf delaycnt,W bz dr_nodelay ;delay is counting decfsz delaycnt goto dr_nodelay ;reached zero movf doortime,W movwf doorcnt ;set relay ON time ; bsf iobuf, 5 dr_nodelay ;door movf doorcnt,W ; bz dr_nodoor btfss STATUS, Z decf doorcnt dr_nodoor ;set relay movf doorcnt,W btfss STATUS, Z ; bz dr_off bsf iobuf, 5 ;relay ON retlw 0 ;dr_off bcf iobuf, 5 ;relay OFF ; retlw 0 ringer_sub ; ;check if the status changed movf ringer,W xorwf prevring,W bz rg_unchanged ;ringer status changed btfss ringer,4 ;test status goto rg_release ;release ; ;ringer pressed, reset counter clrf ringcnt ; rg_unchanged btfsc ringer,4 ;test button status incf ringcnt ;measure pressing time ; retlw 0 ; rg_release ;if the ringer is just released ; movlw 4 subwf ringcnt,W ;check pressing time bnc rg_skip ; ;long enough ringing, open door ; movf doortime,W movwf doorcnt ;set relay ON time ; rg_skip retlw 0 led_sub movf delaycnt,W iorwf doorcnt,W ;idle? bnz led_notidle ;RED in idle or flashing in auto idle movf switch,W bnz led_flash clrf ledpwm ;RED retlw 0 ; led_notidle ;indicate YEL in delay or GRN in opening mode movf doorcnt,W bnz led_door ;delay mode movlw LED_YEL ;YEL movwf ledpwm retlw 0 led_door;door opening mode movlw LED_GRN ;GRN movwf ledpwm retlw 0 led_flash ;flash in auto idle mode movf flashdir,W addwf ledpwm,W andlw 0xe0 ;overflow to the upper 3 bits? btfss STATUS, Z comf flashdir,F ;negate direction movf flashdir,W addwf ledpwm,F retlw 0 setup_sub call setup0 movf switch,W movwf prevsw retlw 0 setup0 ;optional setup for timers btfss button,1 ;test button status retlw 0 ;check if pressed ;button is pressed movf switch,W xorwf prevsw,W btfsc STATUS, Z ;check if the switch state changed retlw 0 ;switch state changed, enter setup mode clrf iobuf ;immediate OFF door relay clrf ledstate2 clrf ledpwm setup1 call delay btfsc IOPORT, 1 ;wait for button release goto setup1 incf ledstate2 ;set RED LED color call readbyte movf temp,W movwf doortime call readbyte movf temp,W movwf delaytime goto warm readbyte clrf temp nop ;BUG!! call read1 ;first 4 bits, then second half nop ;BUG!! swapf temp,F read1 clrf btcnt read0 call delay incf btcnt movlw .20 ;timeout=2 seconds subwf btcnt,W bc read_timeout btfss IOPORT, 1 ;wait for button press goto read0 ;button pressed incf temp ;increase value read2 call delay btfsc IOPORT, 1 ;wait for button release goto read2 goto read1 read_timeout movlw LED_GRN ;indicate timeout movwf ledpwm call delay call delay clrf ledpwm nop ;BUG!! retlw 0 ;;PATCH for the STACKOFL bug (only 12c508) swapf temp,F read1b clrf btcnt read0b call delay incf btcnt movlw .20 ;timeout=2 seconds subwf btcnt,W bc read_timeout_b btfss IOPORT, 1 ;wait for button press goto read0b ;button pressed incf temp ;increase value read2b call delay btfsc IOPORT, 1 ;wait for button release goto read2b goto read1b read_timeout_b movlw LED_GRN ;indicate timeout movwf ledpwm call delay call delay clrf ledpwm retlw 0 ;;PATCH for the STACKOFL bug (only 12c508) end ; directive 'end of program'