Речь идёт о маленькой плате в формате реле, которая может быть установлена вместо реле в панельку. На входе её +12 вольт и ШИМ-сигнал по минус 12 вольт. На выходе - симистор, который обеспечивает фазовую регулировку нагрузки пропорционально входящего ШИМ.
Вот схема: Вот прошивка на текущий момент:
Код: Выделить всё
#include p10f322.inc
;====================================================================
; Variables
;====================================================================
PWMIN equ RA0 ; Port PWM
ZC equ RA1 ; Port Zero Cross
OUT equ RA2 ; Port MOC
ON equ 0x00; FIRE ENABLE
FULL equ 0x01; ON/OFF TRIAC
I equ 0x02; INT ENABLE
CH equ 0x03; INT ENABLE
constant Period = 0x73 ; (100 Hz)
constant C.input_mask = (1<<PWMIN)
constant fixdec = 0x01
constant mindim = 0x1E
constant onfire = 0x03
constant PWMperiod = 0x50 ;0x64 ;(383 Hz)
constant FULLcount = 0x09
; Variables (0x40 thru 0x7F)
udata
W_TEMP res 1
STATUS_TEMP res 1
NCOtmp res 1
count res 1
TMP res 1
FIRE res 1
PORTAtmp res 1
inputs.this_time res 1
inputs.last_time res 1
edgeR.detected res 1
edgeF.detected res 1
;====================================================================
; RESET and INTERRUPT VECTORS
;====================================================================
org 0x00 ; RESET VECTOR
goto START
org 0x04 ; INTERRUPT VECTOR
MOVWF W_TEMP ;Copy W to TEMP register
SWAPF STATUS,W ;Swap status to be saved into W
;Swaps are used because they do
;not affect the status bits
MOVWF STATUS_TEMP ;Save status to bank zero STATUS_TEMP register
BSF FIRE,I
BTFSC INTCON,TMR0IF ; INTERRUPT TMR0
GOTO TRIAC.OFF
BTFSC PIR1,TMR2IF ; INTERRUPT TMR2
GOTO INTTMR2
BTFSC INTCON,IOCIF ; INTERRUPT-ON-CHANGE
GOTO SIN.START
GOTO ENDOFINT
TRIAC.OFF
BTFSS FIRE,FULL
BCF LATA,OUT
BCF INTCON,TMR0IF
BCF INTCON, TMR0IE
BCF T2CON,TMR2ON
BCF PIR1, TMR2IF
CLRF TMR2
GOTO ENDOFINT
SIN.START
BTFSS IOCAF, ZC ; INTERRUPT-ON-CHANGE PORTA
GOTO ENDOFINT
MOVLW (1 << ZC)
XORWF IOCAF, W
ANDWF IOCAF, F
BTFSC PORTA, ZC
GOTO ENDOFINT
BSF T2CON,TMR2ON
MOVLW Period
MOVWF TMR0
BCF INTCON, TMR0IF
BSF INTCON, TMR0IE
GOTO ENDOFINT
INTTMR2
BSF LATA,OUT
BCF T2CON,TMR2ON
BCF PIR1, TMR2IF
ENDOFINT
SWAPF STATUS_TEMP,W ;Swap STATUS_TEMP register into W
;(sets bank to original state)
MOVWF STATUS ;Move W into STATUS register
SWAPF W_TEMP,F ;Swap W_TEMP
SWAPF W_TEMP,W ;Swap W_TEMP into W
retfie
;====================================================================
; CODE SEGMENT
;====================================================================
START
; OSC 4MHz (default 8MHz)
CLRF TMP
MOVLW b'00100000'
MOVWF TMP
MOVLW b'01110000'
IORWF OSCCON,W
XORWF TMP,W
MOVWF OSCCON
; INIT VARS
; INIT PORTA
CLRF PORTA
CLRF LATA
CLRF ANSELA ;Ports all digital
; After reset all ports as input
bsf TRISA,ZC ; Input port Zero Cross
bsf TRISA,PWMIN ; Input port PWM
BCF TRISA,OUT
;BSF WPUA,PWMIN
; TMR0 INIT
MOVLW b'10000101' ;1:64 tmr0 prescaler, pullups disable
MOVWF OPTION_REG
; TMR2 INIT
MOVLW b'00000011' ;1:64 tmr2 prescaler, 1:1 postscaler, tmr2 off
MOVWF T2CON
MOVLW 0xFF
MOVWF PR2
BSF PIE1,TMR2IE ; Interrup TMR2 Enable
; NCO INIT
MOVLW b'00000001'
MOVWF NCO1CLK
CLRF NCO1CON
CLRF NCO1ACCL
CLRF NCO1ACCH
CLRF NCO1ACCU
MOVLW PWMperiod
MOVWF NCO1INCL
BSF NCO1CON,N1EN ; NCO Enable
;INTC
BSF IOCAN,ZC ; Int for ZC negativ front
BSF INTCON,IOCIE ; Enable Interrupt-on-Change
BSF INTCON,PEIE ; Peripheral Interrupt
BSF INTCON,GIE ; Global Interrupt Enable
CLRF FIRE
CLRF NCOtmp
MOVLW FULLcount
MOVWF count
MAINLOOP
BTFSS PIR1,NCO1IF
goto edge.rise
DECFSZ count
goto clr.nco
BSF FIRE,FULL
MOVLW FULLcount
MOVWF count
clr.nco
BCF PIR1,NCO1IF
CLRF NCO1ACCL
CLRF NCO1ACCH
CLRF NCO1ACCU
goto MAINLOOP
edge.rise
movfw PORTA ; load PORTA to Wreg
andlw C.input_mask ; mask out I/O bits we're not interested in
movwf inputs.this_time ; save result to variable
xorwf inputs.last_time,W ; XOR last input value with current input value
andwf inputs.this_time,W ; keep only bits that have changed from 0 to 1
movwf edgeR.detected ; save result to variable;
movf inputs.this_time,W ; load result to variable
xorwf inputs.last_time,W ; XOR last input value with current input value
andwf inputs.last_time,W ; keep only bits that have changed from 0 to 1
movwf edgeF.detected
movfw inputs.this_time ; copy input.this_time to
movwf inputs.last_time
BTFSC edgeR.detected, PWMIN
goto tmr0.start
BTFSC edgeF.detected, PWMIN
goto tmr0.stop
;goto MAINLOOP
MOVF NCOtmp,W
MOVWF PR2
goto MAINLOOP
BCF STATUS,Z
BCF STATUS,C
SUBWF PR2,W
BTFSC STATUS,Z
INCF PR2,F
BTFSC STATUS,C
DECF PR2,F
BTFSS STATUS,C
INCF PR2,F
goto MAINLOOP
tmr0.start
CLRF NCO1ACCL
CLRF NCO1ACCH
CLRF NCO1ACCU
goto MAINLOOP
tmr0.stop
BCF NCO1CON,N1EN ;NCO Disable
MOVLW b'11110000'
ANDWF NCO1ACCH,W
ADDWF NCO1ACCU,W
BTFSC FIRE,I
goto tmr0.stop.1
MOVWF NCOtmp
SWAPF NCOtmp,F
BCF FIRE,FULL
tmr0.stop.1
BCF FIRE,I
MOVLW FULLcount
MOVWF count
BSF NCO1CON,N1EN ;NCO Enable
goto MAINLOOP
TableHi
ADDWF PCL,F
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
TableLo
ADDWF PCL,F
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
RETLW 0x00
;====================================================================
END
Схема и прошивка диммера опубликованы на условиях лицензии CC BY-NC-SA.