;************************************************************************** ; FILE: strength.asm * ; CONTENTS: 'Strengthometer' * ; COPYRIGHT: MadLab Ltd. 1999 * ; AUTHOR: James Hutchby * ; UPDATED: 23/09/99 * ;************************************************************************** list p=12C508A include "p12c508a.inc" ; __config _IntRC_OSC & _WDT_ON & _MCLRE_OFF & _CP_OFF __config _IntRC_OSC & _WDT_ON & _MCLRE_OFF & _CP_ON __idlocs h'BE11' errorlevel -305 ;************************************************************************** ; * ; Specification * ; * ;************************************************************************** ; power-up self-test: all LEDs flash briefly twice ; auto calibrates: baseline = initial light level ; light level continually sensed and displayed on LED bar ;************************************************************************** ; * ; Port assignments * ; * ;************************************************************************** GPIO_IO equ b'001000' ; GPIO I/O status #define SOURCE GPIO,5 ; source LED #define SENSOR GPIO,3 ; sensor LED BAR0 equ d'8'+2 ; LED bar #0 BAR1 equ 1 ; LED bar #1 BAR2 equ d'8'+1 ; LED bar #2 BAR3 equ 0 ; LED bar #3 BAR4 equ d'8'+0 ; LED bar #4 BAR_MASK equ b'000111' ; LED bar mask BAR_MUX equ 4 ; LED bar multiplexer ;************************************************************************** ; * ; Constants and timings * ; * ;************************************************************************** CLOCK equ d'4000000' ; processor clock frequency in Hz PRESCALE equ b'11000000' ; prescale RTCC 1:2 (weak pull-ups ; disabled, no wake-up on pin change) INTEGRATE equ d'3' ; integrator time constant (~12ms) ;************************************************************************** ; * ; File register usage * ; * ;************************************************************************** RAM equ h'07' cblock RAM baseline ; baseline light level bar ; LED bar position, 0 to 15 pattern ; LED bar pattern duty ; source LED duty, 0 to 255 phase ; duty cycle phase BAR_A, BAR_B ; port data repeat ; repeat counter delay ; delay counter bits ; bit counter arg1, arg2 ; 8-bit arguments result_hi, result_lo ; 16-bit result timer_hi, timer_lo ; sleep timer work1, work2 ; work registers endc ;************************************************************************** ; * ; Macros * ; * ;************************************************************************** routine macro label ; routine label endm table macro label ; define lookup table label addwf PCL endm entry macro value ; define table entry retlw value endm index macro label ; index lookup table call label endm jump macro label ; jump through table goto label endm tstw macro ; test w register iorlw 0 endm movff macro f1,f2 ; move file to file movfw f1 movwf f2 endm movlf macro n,f ; move literal to file movlw n movwf f endm ;-------------------------------------------------------------------------- ; reset vector ;-------------------------------------------------------------------------- org 0 movwf OSCCAL goto main_entry ;************************************************************************** ; * ; Lookup tables * ; * ;************************************************************************** table patterns ; LED bar patterns pattern_ macro leds,repeat variable i = repeat while i > 0 entry leds i set i-1 endw endm pattern_ b'00000',1 pattern_ b'10000',1 pattern_ b'01000',1 pattern_ b'00100',1 pattern_ b'00010',2 pattern_ b'00001',2 pattern_ b'10001',2 pattern_ b'01001',2 pattern_ b'00101',3 pattern_ b'00011',3 pattern_ b'10011',3 pattern_ b'01011',3 pattern_ b'00111',4 pattern_ b'10111',4 pattern_ b'01111',4 pattern_ b'11111',4 NUM_PATTERNS equ $-patterns-1 MAX_BAR equ NUM_PATTERNS-1 ;************************************************************************** ; * ; Procedures * ; * ;************************************************************************** ;-------------------------------------------------------------------------- ; multiplication (8-bit arg1 * 8-bit arg2 -> 16-bit result) ;-------------------------------------------------------------------------- routine mult clrf result_hi clrf result_lo clrf work1 movlf d'8',bits mult1 rrf arg1 bnc mult2 movfw arg2 addwf result_lo skpnc incf result_hi movfw work1 addwf result_hi mult2 clrc rlf arg2 rlf work1 decfsz bits goto mult1 retlw 0 ;-------------------------------------------------------------------------- ; division (16-bit result / 8-bit arg1 -> 8-bit result) ;-------------------------------------------------------------------------- routine div clrf work1 movlf d'16',bits div1 clrc rlf result_lo rlf result_hi rlf work1 bc div2 movfw arg1 subwf work1,w bnc div3 div2 bsf result_lo,0 movfw arg1 subwf work1 div3 decfsz bits goto div1 retlw 0 ;-------------------------------------------------------------------------- ; duty cycle ;-------------------------------------------------------------------------- routine duty_cycle movlf INTEGRATE,repeat duty0 movlw GPIO_IO ; re-initialise port tris GPIO movlw PRESCALE ; prescale RTCC option do_bit macro bit,led btfsc pattern,bit if led < d'8' bsf BAR_A,led else bcf BAR_B,led-d'8' endif endm clrf BAR_A ; determine port data movlf BAR_MASK,BAR_B do_bit 0,BAR0 do_bit 1,BAR1 do_bit 2,BAR2 do_bit 3,BAR3 do_bit 4,BAR4 bsf BAR_B,BAR_MUX movfw BAR_A ; multiplex LED bar btfsc phase,0 movfw BAR_B movwf GPIO movff duty,work1 ; ~ duty * 16 us bz duty2 bsf SOURCE ; duty cycle 'on' duty1 clrwdt nop nop nop nop nop nop nop nop nop nop nop nop decfsz work1 goto duty1 duty2 movlf d'255',work1 ; ~ (255 - duty) * 16 us movfw duty subwf work1 bz duty4 bcf SOURCE ; duty cycle 'off' duty3 clrwdt nop nop nop nop nop nop nop nop nop nop nop nop decfsz work1 goto duty3 duty4 incf phase ; next phase decfsz repeat goto duty0 bsf SENSOR ; test sensor LED nop btfss SENSOR goto duty5 incf duty ; lengthen 'on' pulse skpnz decf duty goto duty6 duty5 tstf duty ; shorten 'on' pulse skpz decf duty duty6 retlw 0 ;-------------------------------------------------------------------------- ; main entry point ;-------------------------------------------------------------------------- routine main_entry clrf GPIO ; initialise port movlw GPIO_IO tris GPIO movfw STATUS ; wake-up from sleep ? andlw (1<