
;
; pic 4 dummies..
; This is a phase first slicer for the 16C84 - documented in broken inglisch ;-(
; assemble me with: picasm dimm.asm <CR>
; $VER: dimmer.asm V1.42 (19.09.97)
; ©: This program is free software and can be used and distributed
; ©: under the terms of the GNU General Public License.
;


  list  p=PIC16C84, r=dec, s=on
;                          ^interpret the code as case sensItive
;                   ^radix is decimal
;       ^the `84 is the target processor



  device hs_osc,protect_off,wdt_off
;                           ^the watchdog sleeps ;-)
;               ^no read protection
;        ^config the osilator in high-speed mode



  XTAL 4000000 ;crystal freq. for Amiga Picsim [Hz]

  include "ram:p16c84.inc" ; load this include-file


;some definitions ...

#define ELR PORTA,2 ; led-triac modul (via 470R)
#define POWER_LINE PORTA,3 	; 100V - 250V AC (via 2 * 4M7 in series !)
                           	;    W A R N I N G !¡! HIGH VOLTAGE !!!


#define DARKER  PORTB,4   	; connect this pin to ground to make it darker
#define BRIGHTER  PORTB,5 	; connect this pin to ground to make it brighter

; these are the definitions work in  MY circuit (230V 50Hz)

#define IGNITION_DELAY 30 	; the led of the power modul must be on for at least
                          	; some µ seconds
#define IGNITION_PRESET 128 	; about 90° first slice
#define DIMM_MIN 15  		;max.  value off the fileregister dimm


DIMM_MAX 	=  200   	; min.  value off the fileregister dimm
DIMM_X 		=  254   	; min.  value off the fileregister dimm

XTAL 		= 4000000 	;crystal freq. for delay-time calulations [Hz]
LINE_FREQ 	= 50 		;power_line freq. [Hz]

CLOCKCYCLES_PER_INSTRUCTIONS = 4

IPHW 		= XTAL/CLOCKCYCLES_PER_INSTRUCTIONS/LINE_FREQ/2

; IPHW 	= Instruction Per HalvWave( i.e. 10ms @ 50Hz)


INSTRUCTIONCYCLES_PER_DELAYCYC = 3

;DIMM_WAIT 	= ((IPHW-50)/DIMM_MAX+20)/ INSTRUCTIONCYCLES_PER_DELAYCYC
DIMM_WAIT 	= (IPHW-122-DIMM_X*8)/ (INSTRUCTIONCYCLES_PER_DELAYCYC * DIMM_X)


; some very simple macros..

    macro elr_off
            bcf ELR ; LED of the powermodul off
    endm

    macro elr_on
            bsf ELR ; LED of the powermodul on
    endm


; some fileregisters are defined here...
  CBLOCK  0xc
  dimm
  dimm_counter
  wait_counter
  ENDC



  org 0x0 ; the program starts at 0x0000

init ; do the necessary initializations here ...

            clrf PORTA 		; clear both ports
            clrf PORTB

            bsf STATUS, RP0   	; switch to bank 1

            bcf OPTION_REG, 7 		; PORTB pull-ups are enabled (for the 2 keys)
;****            bcf OPTION_REG, RBPU 	; PORTB pull-ups are enabled (for the 2 keys)

            movlw 0x0
            movwf TRISB
            movwf TRISA
                              	; TRISA(B) and PORTA(B) are the same ...
            bsf POWER_LINE    	; these pins are inputs (in=1, out=0)
            bsf DARKER
            bsf BRIGHTER

            bcf STATUS, RP0   	; switch back to bank 0


            movlw IGNITION_PRESET
            movwf dimm


main_loop
            call wait_line_change  ; call a subroutine
            movf dimm,w  	; transfer the the data form the "dimm" file-register
                         	;  into the working register
            call dimm_it
            btfss BRIGHTER 	; test if the BRIGHTER pin is low
              incf dimm 	; ok, it`s low, increment dimm by one
            btfss DARKER   	; test if the DARKER pin is low
              decf dimm 	; ok, it`s low, decrement dimm by one

            movlw DIMM_MIN 	; move DIMM_MIN in the working register
            subwf dimm,w  	; subtract w from dimm and store the result in w
            btfsc STATUS, Z 	; is last result Zero ?
              incf dimm   	; yes -> inc. dimm

            movlw DIMM_MAX 	; same with the upper limit...
            subwf dimm,w
            btfsc STATUS, Z
              decf dimm 	; ...but here we decrease dimm

            goto main_loop 	; jump to main_loop and repeat this stuff forever...


dimm_it
            movwf dimm_counter   ; copy w in dimm_counter
            comf dimm_counter,f   ; generate the complement of dimm_counter and
                                  ; store it in dimm_counter
dimm_loop
            call wait
            decfsz dimm_counter
              goto dimm_loop
            elr_on 		;  macro:     bsf     PORTA, ELR
            call ignition_wait	; wait some µ seconds
            elr_off ;  macro:     bcf     PORTA, ELR
            return

wait 				; ... a small delay routine ...
            movlw DIMM_WAIT
            movwf wait_counter
wait_loop
            decfsz wait_counter
              goto wait_loop
            return


ignition_wait 			; the TRIAC need some time (µs) to ignite
            movlw IGNITION_DELAY
            movwf wait_counter
i_wait_loop
            decfsz wait_counter
              goto i_wait_loop
            return


wait_line_change 		; wait until the level of the POWER_LINE pin change
            btfss POWER_LINE
              goto line_is_low
line_is_high
            btfsc POWER_LINE
              goto line_is_high
            return 		;return from subroutine
line_is_low
            btfss POWER_LINE
              goto line_is_low
            return



;CAUTION: To prevent a electric shock this circuit should be build and operated
;         by qualified persons ONLY !
;
;
; and now some ASCII-art... (try another font if you see no art :-)
;
;
;                      R1     R2      *               +5V  R4  [4]
;     -------------x--vvvv---vvvv----|                  |-vvvv-|
;     |            |                --------------------------------
;   L o           ---------   R3   |[2]                Vdd[14]  [11]|--------
; 100-250 VAC    |powermod.|-vvvv--|[1]                             |       |
;   N O           ---------        |           PIC16C84             |       |
;     |    \ /     |     |         |                   GND[5]   [10]|-|     |
;     x-----X------|     |          --------------------------------   /     /
;     |    / \           |                               |            /     /
;     -------------------x-------------------------------x------------x-----x
;
; *:the µC has internal diodes from most pins to the powerrails
;    i.e. the voltage is not beyond the absolute maximum ratings if the current
;    is limited by a resistor.
;
;                     [x]   = pin nr. x
;
;
;                     vvvv  = resistor
;
;               |     |
;          |----|-----|--|
;          |    |   <-L  |  =  the powermodul
;          |  TRIAC <-E  |
;          |    |   <-D  |
;          |----|-----|--|
;               |     |
;
;
;                       |
;                        /  = key
;                       /
;                       |
;
;                      \ /
;                       X   = bulb  (only Ohmic resistance !)
;                      / \
;
; R1 = R2 = 4M7
; R3 = 470R
; R4 = 10K
;
;Klaus


