; ------ uP POWER CONTROLLER ------ ; ------ Processor AT89C2051 24PC ------ ;#DEFINE DEBUG ;Debugger on/off ;#DEFINE ASYNCEN ;enables out pin in asynchronous mode ;#DEFINE UNLIMOUT ;unlimited out pulse length (else 4 MS) #INCLUDE "LIBREG.ASM" ;8051 SFR set #INCLUDE "LIBMAC.ASM" ;macros set CLK_KHZ = 12000 ;OSC frequency, KHZ RTC_MS = 22 ;initial mains pulse wait time, MS #INCLUDE "LIBRTC.ASM" ;calculate RTCV INTV .EQU RTCV ;INTV <- RTCV RTC_MS = 4 ;indication scan rate, MS #INCLUDE "LIBRTC.ASM" ;calculate RTCV #IFDEF DEBUG #INCLUDE "LIBDEF.ASM" #ENDIF ; ------ Constantes ------ STACK .EQU 056H ;stack location POW100 .EQU 100 ;max. power mode 1 POW10 .EQU 10 ;max. power mode 2 KEYDB .EQU 5 ;key debounce delay (x10mS) KEYDA .EQU 70 ;key autorepeat delay (x10mS) KEYARR .EQU 15 ;autorepeat rate (x10mS) KEYFARR .EQU 15 ;fast autorepeat rate (x10mS) ARCOUNT .EQU 10 ;autorepeat to fast autorepeat count ; ------ Debugger variables ------ #IFDEF DEBUG DBGVA .EQU STACK-1 ;debugger variable address in internal memory DBGVV .EQU STACK ;debugger variable value in internal memory DBGA .EQU 0FFH ;debugger address in external memory #ENDIF ; ------ Ports ------ SEG_A .EQU P1.2 ;indicators segment A SEG_B .EQU P1.3 ;indicators segment B SEG_C .EQU P1.4 ;indicators segment C SEG_D .EQU P1.5 ;indicators segment D SEG_E .EQU P1.6 ;indicators segment E SEG_F .EQU P1.7 ;indicators segment F SEG_G .EQU P3.7 ;indicators segment G SEG_H .EQU T1 ;indicators segment H (1XX) SCAN0 .EQU TXD ;display scan line 1 SCAN1 .EQU RXD ;display scan line 2 JUMPER .EQU SEG_H ;jumper KEY_UP .EQU INT1 ;UP key KEY_DN .EQU T0 ;DOWN key PWM .EQU INT0 ;PWM out ; ------ Variables ------ ; Bit addressing memory PRESS .EQU M_20H.0 ;keyboard press bit SIGN .EQU 021H ;mains sign PHASE .EQU 022H ;PWM phase POWER .EQU 023H ;power level DELTA .EQU 024H ;PWM_100 internal variable KEYDBT .EQU 025H ;key debounce timer KEYTM .EQU 026H ;key timer PREV .EQU 027H ;previous key code MAXPOW .EQU 028H ;max. power value REPCNT .EQU 029H ;repeat counter ; ------ Vectors Area ------ .ORG 0000H ;reset vector ; ------ Main Program ------ MOV SP,#STACK ;stack init #IFDEF DEBUG DEBUGINIT ;debug init #ENDIF MOV MAXPOW,#POW100 JB JUMPER,M100 MOV MAXPOW,#POW10 M100: CLR PRESS ;clear keyboard press bit CLR A MOV PREV,A MOV SIGN,A MOV POWER,A MOV DPTR,#FONT MOV A,MAXPOW MOV PHASE,A CLR C RRC A CPL A INC A MOV DELTA,A CLR TR0 CLR TR1 CLR TF0 MOV TMOD,#11H ;timer 0 and timer 1 init MOV TH0,#HI(INTV) ;indication timer load MOV TL0,#LO(INTV) SETB TR0 ;timer start ;======== Comparator out check ======== MAIN: #IFDEF ASYNCEN JB TF0,PWM0 ;jump if no mains pulses #ELSE JB TF0,PWM2 ;jump if no mains pulses #ENDIF MOV A,P3 ;comparator out check XRL A,SIGN JNB ACC.6,MAIN ;loop if same mains sign XRL SIGN,#0FFH ;change sign ;======== PWM out control ======== PWM0: MOV A,POWER ADD A,DELTA MOV DELTA,A MOV C,ACC.7 MOV PWM,C JC PWM1 SUBB A,MAXPOW MOV DELTA,A PWM1: DJNZ PHASE,PWM2 MOV A,MAXPOW MOV PHASE,A CLR C RRC A CPL A INC A MOV DELTA,A ;======== Indicate 1s ======== PWM2: CLR TR0 MOV TH0,#HI(RTCV) ;indication timer load MOV TL0,#LO(RTCV) CLR TF0 SETB TR0 ;timer start MOV A,POWER MOV B,#10 DIV AB ;A=10s, B=1s MOV A,B MOVC A,@A+DPTR ACALL IND SETB SCAN1 CLR SCAN0 ;indicate 1s ;======== Keyboard check ======== MOV C,KEY_UP ;keyboard check ANL C,KEY_DN JC NP ;jump if no press MOV A,#0FFH MOV C,KEY_UP RLC A MOV C,KEY_DN RLC A CPL A ;ACC.1 - UP, ACC.0 - DN MOV R0,A XRL A,PREV JNZ ND MOV A,KEYDBT JZ DOV DEC KEYDBT SJMP W1 ;jump if debounce delay is not over DOV: CJNE R0,#1,NDN ACALL DO_DN ;DOWN pressed NDN: CJNE R0,#2,NUP ACALL DO_UP ;UP pressed NUP: CJNE R0,#3,NUD ACALL DO_UD ;UP+DOWN pressed NUD: SETB PRESS SJMP W1 ND: MOV PREV,R0 NP: CLR PRESS MOV KEYDBT,#KEYDB ;debounce timer load W1: JNB TF0,$ ;======== PWM out off ======== #IFNDEF UNLIMOUT SETB PWM ;PWM out off #ENDIF ;======== Indicate 10s ======== CLR TR0 MOV TH0,#HI(RTCV) ;indication timer load MOV TL0,#LO(RTCV) CLR TF0 SETB TR0 ;timer start MOV A,POWER MOV B,#10 DIV AB ;A=10s, B=1s JNZ NZ MOV A,#0DH ;blank code NZ: MOVC A,@A+DPTR ACALL IND SETB SCAN0 CLR SCAN1 ;indicate 10s ;======== Program timer check ======== MOV A,KEYTM JZ W2 DEC KEYTM ;advance key timer W2: JNB TF0,$ ;======== Indication off ======== CLR TR0 MOV TH0,#HI(RTCV) ;indication timer load MOV TL0,#LO(RTCV) CLR TF0 SETB TR0 ;timer start SETB SCAN0 SETB SCAN1 ;indication off AJMP MAIN ;main loop ; ------ Subroutines Area ------ ;UP key processing: DO_UP: JB PRESS,UPH ;jump if key hold MOV KEYTM,#KEYDA ;first press, autorepeat delay load MOV REPCNT,#0 ;autorepeat counter clear SJMP UP_DO UPH: MOV A,KEYTM ;KEYTM check JNZ UP_RET CLR C MOV KEYTM,#KEYARR ;load normal repeat rate MOV A,REPCNT SUBB A,#ARCOUNT ;REPCNT check JC UP_DO ;jump if REPCNT < ARCOUNT MOV KEYTM,#KEYFARR ;load fast repeat rate UP_DO: MOV A,POWER XRL A,MAXPOW JZ UP_RET ;jump if limit INC POWER ;power inc. INC REPCNT ;autorepeat counter inc. UP_RET: RET ;DOWN key processing: DO_DN: JB PRESS,DNH ;jump if key hold MOV KEYTM,#KEYDA ;first press, autorepeat delay load MOV REPCNT,#0 ;autorepeat counter clear SJMP DN_DO DNH: MOV A,KEYTM ;KEYTM check JNZ DN_RET CLR C MOV KEYTM,#KEYARR ;load normal repeat rate MOV A,REPCNT SUBB A,#ARCOUNT ;REPCNT check JC DN_DO ;jump if REPCNT < ARCOUNT MOV KEYTM,#KEYFARR ;load fast repeat rate DN_DO: MOV A,POWER JZ DN_RET ;jump if limit DEC POWER ;power dec. INC REPCNT ;autorepeat counter inc. DN_RET: RET ;UP+DOWN key processing: DO_UD: JB PRESS,UD_RET ;no hold mode MOV A,POWER JZ DO_MAX MOV POWER,#0 ;load MIN power SJMP UD_RET DO_MAX: MOV POWER,MAXPOW ;load MAX power UD_RET: RET ;Segments on/off ;Input: A - segments copy, ACC.0 - A, ACC.1 - B, ... IND: RRC A MOV SEG_A,C RRC A MOV SEG_B,C RRC A MOV SEG_C,C RRC A MOV SEG_D,C RRC A MOV SEG_E,C RRC A MOV SEG_F,C RRC A MOV SEG_G,C RRC A MOV SEG_H,C RET ;Font table ; SGFEDCBA FONT .DB 11000000B ;code 00H, character 0 .DB 11111001B ;code 01H, character 1 .DB 10100100B ;code 02H, character 2 .DB 10110000B ;code 03H, character 3 .DB 10011001B ;code 04H, character 4 .DB 10010010B ;code 05H, character 5 .DB 10000010B ;code 06H, character 6 .DB 11111000B ;code 07H, character 7 .DB 10000000B ;code 08H, character 8 .DB 10010000B ;code 09H, character 9 .DB 01000000B ;code 0AH, character 10 .DB 01111001B ;code 0BH, character 11 .DB 00100100B ;code 0CH, character 12 .DB 11111111B ;code 0DH, character blank #IFDEF DEBUG #INCLUDE "LIBDBG.ASM" #ENDIF .END