;********************************************************************** ; Filename: lampctr.asm * ; Date: 2003-02-22 * ; File Version: 1.0 * ; * ; Author: Per Zander * ;********************************************************************** ; Files required: p16c505.inc * ;********************************************************************** ; Description: ; ; This is a program for turning 8 different lamps on and off in ; different sequences. There are four alternative sequences, that are ; selected by the inputs RB4 and RB5. ; ; Sequence 0 (RB5 and RB4 low). Total 20 s: ; ; On: L0 (5s) L1 (2s) L2 (4s) L3 (1s) L4 (3s) L5 (4s) L6 (1s) L7 ; Off: L4 (2s) L2 (5s) L6 (3s) L1 (2s) L7 (1s) L0 (5s) L5 (2s) L3 ; ; Sequence 1 (RB5 low, RB4 high). Total 11 s on, 13 s off: ; ; On: L0 (2s) L1 (1s) L2 (2s) L3 (1s) L4 (2s) L5 (2s) L6 (1s) L7 ; Off: L4 (1s) L2 (3s) L6 (3s) L1 (1s) L7 (1s) L0 (3s) L5 (1s) L3 ; ; Sequence 2 (RB5 high, RB4 low). Total 20 s: ; ; On: L4 (2s) L2 (5s) L6 (3s) L1 (2s) L7 (1s) L0 (5s) L5 (2s) L3 ; Off: L0 (5s) L1 (2s) L2 (4s) L3 (1s) L4 (3s) L5 (4s) L6 (1s) L7 ; ; Sequence 3 (RB5 and RB4 high). Total 13 s on, 11 s off: ; ; On: L4 (1s) L2 (3s) L6 (3s) L1 (1s) L7 (1s) L0 (3s) L5 (1s) L3 ; Off: L0 (2s) L1 (1s) L2 (2s) L3 (1s) L4 (2s) L5 (2s) L6 (1s) L7 ; ; The selected sequence is started by a positive pulse on RC5. The ; first pulse after reset will start an "on" sequence, next one starts ; an "off" sequence etc. ; ;********************************************************************** ;*---------- Device select. ----------* list p=16c505 ; List directive to define processor #include ; Processor specific variable definitions ;*---------- Configuration specification. ----------* __CONFIG _CP_OFF & _WDT_OFF & _MCLRE_ON & _IntRC_OSC_RB4EN ;*---------- Port definitions. ----------* sel0 EQU 0x04 ; Select0 on RB4 sel1 EQU 0x05 ; Select1 on RB5 din EQU 0x05 ; Data in on RC5 p0 EQU 0x00 ; Port 0 on RB0 p1 EQU 0x01 ; Port 1 on RB1 p2 EQU 0x02 ; Port 2 on RB2 p3 EQU 0x00 ; Port 3 on RC0 p4 EQU 0x01 ; Port 4 on RC1 p5 EQU 0x02 ; Port 5 on RC2 p6 EQU 0x04 ; Port 6 on RC4 p7 EQU 0x03 ; Port 7 on RC3 ;*---------- Variable definitions. ----------* tmp EQU 0x08 ; Temporary variable. short EQU 0x08 medium EQU 0x09 long EQU 0x0a stst EQU 0x0b ; State pointer for start pulse detect. flags EQU 0x0c ; Program flags. seqstep EQU 0x0d ; Where are we in the sequence. seqtmr EQU 0x0e ; Step time. ;*---------- Program flags. ----------* start EQU 0x00 ; Start flag on bit 0. on EQU 0x01 ; Indicates "on" or "off" sequence. ;********************************************************************** ;* The program starts here after reset. ;********************************************************************** ORG 0x3FF ; Processor reset vector. movlw 0x38 ; Osc. cal. value. ORG 0x000 ; Coding begins here. startofprog movwf OSCCAL ; Update register with factory cal value. clrf FSR ; Ensure FSR register points to Bank0. goto init_code ; Jump over a few words to enable ; reprogramming. ORG 0x006 ;*************************************************************** ; A 3.959 ms delay loop, i.e. 3959 instruction cycles. * ; (including call and return time). * ;*************************************************************** wait_4ms movlw 4 movwf medium wait_4ms_outer movlw 0xf6 movwf short wait_4ms_inner nop decfsz short, F goto wait_4ms_inner wait_4ms_endi decfsz medium, F goto wait_4ms_outer goto wait_4ms_end wait_4ms_end retlw 0 ;*************************************************************** ; State machine for detecting start pulses. * ; This consumes 13 cycles, including call and return. * ;*************************************************************** ;*---------- Jump to current state. ----------* start_det movf stst, W movwf PCL ;*---------- Idle state. ----------* st_idle movlw st_idle btfsc PORTC, din movlw st_hi1 goto st_epilog ;*---------- High detected once. ----------* st_hi1 movlw st_idle btfsc PORTC, din movlw st_hi2 goto st_epilog ;*---------- High detected twice. ----------* st_hi2 movlw st_idle btfsc PORTC, din movlw st_hi3 goto st_epilog ;*---------- High detected three times. ----------* st_hi3 movlw st_idle btfsc PORTC, din bsf flags, start btfsc flags, start movlw st_hi4 st_epilog movwf stst retlw 0 ;*---------- High detected four times. ----------* st_hi4 movlw st_hi4 btfss PORTC, din movlw st_lo1 goto st_epilog ;*---------- Low detected once. ----------* st_lo1 movlw st_hi4 btfss PORTC, din movlw st_lo2 goto st_epilog ;*---------- Low detected twice. ----------* st_lo2 movlw st_hi4 btfss PORTC, din movlw st_lo3 goto st_epilog ;*---------- Low detected three times. ----------* st_lo3 movlw st_hi4 btfss PORTC, din movlw st_idle goto st_epilog ;*************************************************************** ; Sequence subroutine. Set a lamp and return the next * ; interval time (in units of 0.1 seconds). Takes 21 cycles. * ; It uses a sequence table in the upper program bank. * ;*************************************************************** sequence movf seqstep, W movwf tmp rlf tmp, F ; Sequence step * 2. bcf tmp, 0 btfss flags, on bsf tmp, 4 ; Add 16 if "off" sequence. btfsc PORTB, sel0 ; Select alternative. bsf tmp, 5 btfsc PORTB, sel1 bsf tmp, 6 movlw new_tab & 0xff movlw seq_tab & 0xff ; Make this a nop if a new table is loaded. addwf tmp, W bsf STATUS, PA0 ; Select upper bank. movwf PCL ; Jump into table. ;*************************************************************** ; Short delay. * ;*************************************************************** short_del retlw 0 ;*************************************************************** ; Main program. * ;*************************************************************** ;*---------- Here is the initialization code. ----------* init_code movlw 0xc7 ; Internal timer clock, max prescaler. option clrf PORTB ; Clear output ports. clrf PORTC movlw 0x38 ; Set output ports to out. tris PORTB movlw 0x20 tris PORTC clrf flags movlw st_idle movwf stst movlw 0x08 movwf seqstep movlw 0x19 movwf long movlw 0x01 movwf seqtmr ;*---------- Here is the main loop. ----------* main call wait_4ms ; t0 - t3958 call start_det ; t3959 -t3971 call short_del call short_del call short_del call short_del btfss flags, start ; t3988 goto no_start bcf flags, start movlw 2 xorwf flags, F ; Toggle on/off state. clrf seqstep ; Start the sequence. call short_del goto main ; t3999 no_start btfsc seqstep, 3 ; t3991 goto no_seq ; No sequence running if seqstep = 8. decfsz long, F goto go_main ; t3995 ; long timed out. movlw 0x19 movwf long ; Re-initialize long. decfsz seqtmr, F goto main ; t3999 ;----- Here we go to the next step in the sequence. -----* nop call wait_4ms ; t0 - t3974 call start_det ; t3959 - t3971 call sequence ; t3972 - t3991 bcf STATUS, PA0 ; Select program bank 0. movwf seqtmr incf seqstep, F decf long, F nop goto main ;----- Some steps to equalize loop timing. -----* no_seq goto go_main go_main nop nop goto main ; t3999 ;*************************************************************** ; Sequence tables. Set a lamp and return the next * ; interval time (in units of 0.1 seconds). * ;*************************************************************** org 0x200 new_tab org 0x280 ; Allows a new table to be loaded at 0x200. seq_tab ;----- On sequence 0. -----* bsf PORTB, p0 retlw 0x32 ; 50 decimal. bsf PORTB, p1 retlw 0x14 ; 20 decimal bsf PORTB, p2 retlw 0x28 ; 40 decimal bsf PORTC, p3 retlw 0x0a ; 10 decimal bsf PORTC, p4 retlw 0x1e ; 30 decimal bsf PORTC, p5 retlw 0x28 bsf PORTC, p6 retlw 0x0a bsf PORTC, p7 retlw 1 ;----- Off sequence 0. -----* bcf PORTC, p4 retlw 0x14 bcf PORTB, p2 retlw 0x32 bcf PORTC, p6 retlw 0x1e bcf PORTB, p1 retlw 0x14 bcf PORTC, p7 retlw 0x0a bcf PORTB, p0 retlw 0x32 bcf PORTC, p5 retlw 0x14 bcf PORTC, p3 retlw 1 ;----- On sequence 1. -----* bsf PORTB, p0 retlw 0x14 bsf PORTB, p1 retlw 0x0a bsf PORTB, p2 retlw 0x14 bsf PORTC, p3 retlw 0x0a bsf PORTC, p4 retlw 0x14 bsf PORTC, p5 retlw 0x14 bsf PORTC, p6 retlw 0x0a bsf PORTC, p7 retlw 1 ;----- Off sequence 1. -----* bcf PORTC, p4 retlw 0x0a bcf PORTB, p2 retlw 0x1e bcf PORTC, p6 retlw 0x1e bcf PORTB, p1 retlw 0x0a bcf PORTC, p7 retlw 0x0a bcf PORTB, p0 retlw 0x1e bcf PORTC, p5 retlw 0x0a bcf PORTC, p3 retlw 1 ;----- On sequence 2. -----* bsf PORTC, p4 retlw 0x14 bsf PORTB, p2 retlw 0x32 bsf PORTC, p6 retlw 0x1e bsf PORTB, p1 retlw 0x14 bsf PORTC, p7 retlw 0x0a bsf PORTB, p0 retlw 0x32 bsf PORTC, p5 retlw 0x14 bsf PORTC, p3 retlw 1 ;----- Off sequence 2. -----* bcf PORTB, p0 retlw 0x32 bcf PORTB, p1 retlw 0x14 bcf PORTB, p2 retlw 0x28 bcf PORTC, p3 retlw 0x0a bcf PORTC, p4 retlw 0x1e bcf PORTC, p5 retlw 0x28 bcf PORTC, p6 retlw 0x0a bcf PORTC, p7 retlw 1 ;----- On sequence 3. -----* bsf PORTC, p4 retlw 0x0a bsf PORTB, p2 retlw 0x1e bsf PORTC, p6 retlw 0x1e bsf PORTB, p1 retlw 0x0a bsf PORTC, p7 retlw 0x0a bsf PORTB, p0 retlw 0x1e bsf PORTC, p5 retlw 0x0a bsf PORTC, p3 retlw 1 ;----- Off sequence 3. -----* bcf PORTB, p0 retlw 0x14 bcf PORTB, p1 retlw 0x0a bcf PORTB, p2 retlw 0x14 bcf PORTC, p3 retlw 0x0a bcf PORTC, p4 retlw 0x14 bcf PORTC, p5 retlw 0x14 bcf PORTC, p6 retlw 0x0a bcf PORTC, p7 retlw 1 endofprog END ; directive 'end of program'