;********************************************************** ;*** In the name of God the compassionate the merciful **** ; ;14+an exception: ;sequential pin readings used instead of external interrupts for mechanics microswitches ; ;********************************************************** ;********* HARDWARE PINS ********** DQ BIT P0.0 ;1-Wire data input/output RHPOWER BIT P1.0 ;555 Power control LAMP_OUT BIT P1.1 ;Lamp output for heating air HUMIDIFIER BIT P1.2 ;water heater for humidifying air MOTOR_UP BIT P1.3 MOTOR_DO BIT P1.4 ALARMPIN BIT P1.5 BAKLIGHT BIT P1.7 UPSWITCH BIT P3.2 DOSWITCH BIT P3.3 RS BIT P3.0 ;LCD Data/Instruction select EN BIT P3.1 ;LCD Enable UR BIT P3.6 ;Up/Right OK BIT P3.4 ;OK/Enter DL BIT P3.7 ;Down/Left FREQIN BIT P3.5 ;Relative humidity frequency input ;********* RAM REGISTERS ********** ;R2=SECOND R3=MINUTE R4=HOUR R5=DAY LCDBUF EQU 30H ;LCD Buffer COUNTER EQU 31H ;for counting 1 secnod DlyLC EQU 32H ;DELAY loop counter DlyFactor EQU 33H ;x15us DELAY factor GenLC EQU 34H ;General purpose loop counter GenLC2 EQU 35H ;" TEMPER EQU 36H ;Temperature register SETHATCH EQU 37H ;Set/Hatch status saved in EE ERRORS EQU 38H ;Errors code saved in EE MAXVAL EQU 39H ;Max value allowed for every byte of TIME ;********* FLAGS ****************** HalfDegree BIT 20H.0 GOODRH BIT 20H.1 INCHANGE BIT 20H.2 INTURN BIT 20H.3 INTEST BIT 20H.4 ERRFLAG BIT 20H.5 BEEPFLAG BIT 20H.6 HACHFLAG BIT 20H.7 ;********************************** ORG 0000H MOV P1,#0 LJMP POWERON ORG 000BH LJMP T0ISR ;********************************** POWERON:MOV P1,#0 ;Disabling all outputs MOV P3,#11111100B ;Configuring all inputs MOV TH0,#03CH ;\_50000us MOV TL0,#0AFH ;/ MOV TH1,#0 MOV TL1,#0 MOV IP,#00000010B ;TIMER0 Interrupt priority set high MOV IE,#10000010B ;TIMER0 Interrupt enabled MOV TMOD,#01010001B ;TIMER0 in timer mode1 (16bit)|TIMER1 in counter mode1(16bit) MOV TCON,#01010000B ;Both timers start! MOV COUNTER,#20 MOV R2,#0 MOV R3,#0 MOV R4,#0 MOV R5,#0 MOV 20H,#00 ;initialising all flags as cleared(according to datasheet this should be 00H on reset- ;but that's not so in real world!!!!) LCALL GETSETTING LCALL MANAGE_TURNING START: LCALL LCD_INIT MOV LCDBUF,#080H LCALL LCD_CMD_WR MOV DPTR,#TIMESTR LCALL SENDSTR MOV LCDBUF,#0C0H LCALL LCD_CMD_WR MOV DPTR,#AIRSTR LCALL SENDSTR HOMPAGE:MOV LCDBUF,SETHATCH LCALL LCD_DATA_WR MOV LCDBUF,ERRORS LCALL LCD_DATA_WR LCALL REFRESH_TIME ; **************** SCANKEY: JNB INTURN,NOMOTOCHK SETB DOSWITCH SETB UPSWITCH JNB UPSWITCH,REACHD JNB DOSWITCH,REACHD NOMOTOCHK: JNB OK,GOSETING JNB UR,GOTEST JNB DL,TOGGLEBL JNB ERRFLAG,SCANKEY BEEP: JNB BEEPFLAG,SCANKEY MOV DlyFactor,#10 LCALL DELAY15 CPL ALARMPIN JMP SCANKEY ; **************** REACHD: CLR INTURN CLR MOTOR_DO CLR MOTOR_UP JMP SCANKEY ; **************** TOGGLEBL:LCALL DEBONCE JB DL,SCANKEY LCALL DEBONCE JB DL,SCANKEY CPL BAKLIGHT JNB DL,$ AJMP SCANKEY ; **************** GOSETING:LCALL KEYWAIT JB OK,SCANKEY JNB OK,$ SETB BAKLIGHT SETB INCHANGE CLR ERRFLAG LCALL SETTINGS CLR INCHANGE LJMP HOMPAGE ; **************** GOTEST: LCALL KEYWAIT JB UR,SCANKEY JNB UR,$ SETB BAKLIGHT SETB INTEST SETB INCHANGE LCALL TEST CLR INTEST CLR INCHANGE LJMP START ;********************************** KEYWAIT:MOV GenLC2,#255 L4: MOV DlyFactor,#255 LCALL DELAY15 LCALL DELAY15 DJNZ GenLC2,L4 RET ;********* Timer0 ISR ************* T0ISR: MOV TH0,#03CH ;\_FFFF-3CAF = 50000us X 20 = 1S MOV TL0,#0AFH ;/ DJNZ COUNTER,EXIT MOV COUNTER,#20 CPL BEEPFLAG INC R2 CJNE R2,#60,ENVIRONMENT MOV R2,#0 INC R3 LCALL MANAGE_ALARM CJNE R3,#60,RFRSH_TIME MOV R3,#0 INC R4 LCALL MANAGE_TURNING CJNE R4,#24,RFRSH_TIME MOV R4,#0 INC R5 CJNE R5,#18,RFRSH_TIME MOV SETHATCH,#'H' SETB HACHFLAG MOV LCDBUF,#0C6H LCALL LCD_CMD_WR MOV LCDBUF,SETHATCH LCALL LCD_DATA_WR LCALL SAVESETTING RFRSH_TIME: JB INCHANGE,EXIT LCALL REFRESH_TIME ENVIRONMENT: JB INTEST,EXIT LCALL GETSETSHO_AIR EXIT: RETI ;********************************** MANAGE_TURNING: JB HACHFLAG,NOTURN JB INTURN,NOTURN MOV A,R4 MOV B,#4 DIV AB MOV A,B CJNE A,#0,NOTURN SETB INTURN SETB DOSWITCH SETB UPSWITCH JNB DOSWITCH,ISDOWN CLR TR0 SETB MOTOR_DO JNB UPSWITCH,$ JNB UPSWITCH,$ SETB TR0 JMP NOTURN ISDOWN: JNB UPSWITCH,RAISERR ;If both uSwitches are ON(mechanically impossible!) so there is an error CLR TR0 SETB MOTOR_UP JNB DOSWITCH,$ JNB DOSWITCH,$ SETB TR0 NOTURN: RET ;********************************** MANAGE_ALARM: CJNE R3,#3,CHEK4OFF JNB INTURN,NOALRM RAISERR:CLR INTURN CLR MOTOR_UP CLR MOTOR_DO MOV ERRORS,#'Y' MOV LCDBUF,#0C7H LCALL LCD_CMD_WR MOV LCDBUF,ERRORS LCALL LCD_DATA_WR LCALL SAVESETTING SETB ERRFLAG CHEK4OFF: CJNE R3,#4,NOALRM JNB ERRFLAG,NOALRM CLR ERRFLAG CLR ALARMPIN NOALRM: RET ;********************************** REFRESH_TIME: MOV LCDBUF,#080H LCALL LCD_CMD_WR MOV A,R5 LCALL SHOWBYTE MOV LCDBUF,#083H LCALL LCD_CMD_WR MOV A,R4 LCALL SHOWBYTE MOV LCDBUF,#086H LCALL LCD_CMD_WR MOV A,R3 LCALL SHOWBYTE RET ;********************************** SETTINGS: MOV ERRORS,#'N' MOV LCDBUF,#0C1H LCALL LCD_CMD_WR MOV LCDBUF,SETHATCH LCALL LCD_DATA_WR MOV LCDBUF,#' ' MOV GenLC2,#6 PAD: LCALL LCD_DATA_WR DJNZ GenLC2,PAD MOV LCDBUF,#080H LCALL LCD_CMD_WR MOV LCDBUF,#00001111B LCALL LCD_CMD_WR MOV R1,#5 MOV MAXVAL,#21 SETTIME:LCALL SETBYTE DEC R1 CJNE R1,#4,ONMIN MOV MAXVAL,#23 AJMP MAXDONE ONMIN: MOV MAXVAL,#59 MAXDONE:MOV LCDBUF,#014H LCALL LCD_CMD_WR MOV LCDBUF,#014H LCALL LCD_CMD_WR MOV LCDBUF,#014H LCALL LCD_CMD_WR CJNE R1,#2,SETTIME MOV LCDBUF,#0C1H LCALL LCD_CMD_WR SETSH: JNB DL,TOGGLE JNB UR,TOGGLE JNB OK,SHDONE JMP SETSH TOGGLE: LCALL DEBONCE JNB DL,TOGGLE JNB UR,TOGGLE JNB HACHFLAG,SET2H MOV SETHATCH,#'S' CLR HACHFLAG AJMP SHSHOW SET2H: MOV SETHATCH,#'H' SETB HACHFLAG SHSHOW: MOV LCDBUF,SETHATCH LCALL LCD_DATA_WR MOV LCDBUF,#010H LCALL LCD_CMD_WR AJMP SETSH SHDONE: JNB OK,SHDONE MOV LCDBUF,#00001100B ;Cursor and cursor blink off LCALL LCD_CMD_WR LCALL SHOW_AIR LCALL SAVESETTING RET ;********************************** SETBYTE:JNB DL,DECRIS JNB UR,INCRIS JNB OK,THISDON JMP SETBYTE DECRIS: LCALL DEBONCE DEC @R1 CJNE @R1,#255,DOEVNT MOV @R1,MAXVAL JMP DOEVNT INCRIS: LCALL DEBONCE MOV A,@R1 CJNE A,MAXVAL,VALID MOV @R1,#0 AJMP DOEVNT VALID: INC @R1 DOEVNT: MOV A,@R1 LCALL SHOWBYTE MOV LCDBUF,#010H LCALL LCD_CMD_WR MOV LCDBUF,#010H LCALL LCD_CMD_WR JMP SETBYTE THISDON:LCALL DEBONCE JNB OK,THISDON RET ;********************************** TEST: LCALL LCD_INIT MOV LCDBUF,#080H LCALL LCD_CMD_WR MOV DPTR,#TESTSTR LCALL SENDSTR MOV LCDBUF,#086H LCALL LCD_CMD_WR MOV LCDBUF,#00001111B ;Cursor and cursor blink ON LCALL LCD_CMD_WR SCANTST:LCALL DEBONCE JNB DL,DOWN JNB UR,UP JNB OK,TSTDONE JMP SCANTST DOWN: LCALL DEBONCE MOV P1,#10010110B JNB DL,DOWN MOV P1,#10000000B AJMP SCANTST UP: LCALL DEBONCE MOV P1,#10001110B JNB UR,UP MOV P1,#10000000B AJMP SCANTST TSTDONE:JNB OK,TSTDONE RET ;********************************** DEBONCE:MOV GenLC2,#60 L5: MOV DlyFactor,#200 LCALL DELAY15 DJNZ GenLC2,L5 RET ;********************************** GETSETSHO_AIR: MOV A,R2 MOV B,#10 DIV AB MOV A,B CJNE A,#0,CHKSTART LCALL CONVERT_T SETB RHPOWER JMP EXITG CHKSTART: CJNE A,#1,CHKSTOP MOV TH1,#0 MOV TL1,#0 SETB FREQIN SETB TR1 JMP EXITG CHKSTOP: CJNE A,#2,EXITG CLR TR1 MOV R7,TL1 MOV R6,TH1 CLR RHPOWER CJNE R6,#019H,CHKRH CJNE R7,#0B4H,CHKRH CHKRH: MOV GOODRH,C CPL C MOV HUMIDIFIER,C LCALL READ_T MOV TEMPER,A MOV B,#04BH ;Temperature value 37.5 for set condition JNB HACHFLAG,SETTEMP MOV B,#049H ;Temperature value 36.5 for hatch condition SETTEMP:CJNE A,B,CHKTEMP ;If temperature is below desired,turn lamp output on CHKTEMP:MOV LAMP_OUT,C JB INCHANGE,EXITG LCALL SHOW_AIR EXITG: RET ;********************************** SHOW_AIR: MOV LCDBUF,#0C1H LCALL LCD_CMD_WR LCALL SHOWTEMP JNB GOODRH,RHLESS MOV LCDBUF,#'+' JMP RHDONE RHLESS: MOV LCDBUF,#'-' RHDONE: LCALL LCD_DATA_WR RET ;********************************** SHOWTEMP: MOV A,TEMPER MOV C,ACC.0 MOV HalfDegree,C CLR ACC.0 RR A LCALL SHOWBYTE MOV LCDBUF,#'.' CALL LCD_DATA_WR MOV LCDBUF,#'0' JNB HalfDegree,MOCK ORL LCDBUF,#5 MOCK: CALL LCD_DATA_WR RET ;********************************** SHOWBYTE: MOV B,#10 DIV AB ORL A,#00110000B MOV LCDBUF,A CALL LCD_DATA_WR ORL B,#00110000B MOV LCDBUF,B CALL LCD_DATA_WR RET ;********************************** SENDSTR:CLR A MOVC A,@A+DPTR CJNE A,#0,NEXTCHAR JMP STRDONE NEXTCHAR: MOV LCDBUF,A LCALL LCD_DATA_WR INC DPTR JMP SENDSTR STRDONE:RET ;********************************** CONVERT_T: LCALL OW_RESET MOV A,#0CCH ;"SKIP ROM" Command LCALL WRITE_BYTE MOV A,#44H ;"CONVERT T" Command LCALL WRITE_BYTE LCALL OW_RESET RET ;********************************** READ_T: LCALL READ_SCRATCH LCALL READ_BYTE LCALL OW_RESET RET ;********************************** GETSETTING: LCALL READ_SCRATCH LCALL READ_BYTE LCALL READ_BYTE LCALL READ_BYTE CJNE A,#'H',ISINSET MOV SETHATCH,#'H' SETB HACHFLAG AJMP READERR ISINSET:MOV SETHATCH,#'S' CLR HACHFLAG READERR:LCALL READ_BYTE MOV ERRORS,A LCALL OW_RESET RET ;********************************** READ_SCRATCH: LCALL OW_RESET MOV A,#0CCH ;"SKIP ROM" Command LCALL WRITE_BYTE MOV A,#0BEH ;"READ SCRATCHPAD" Command LCALL WRITE_BYTE RET ;********************************** SAVESETTING: LCALL OW_RESET MOV A,#0CCH ;"SKIP ROM" Command LCALL WRITE_BYTE MOV A,#04EH ;WRITE SCRATCHPAD LCALL WRITE_BYTE MOV A,SETHATCH LCALL WRITE_BYTE MOV A,ERRORS LCALL WRITE_BYTE LCALL OW_RESET MOV GenLC,#250 L3: MOV DlyFactor,#200 LCALL DELAY15 DJNZ GenLC,L3 LCALL OW_RESET MOV A,#0CCH ;"SKIP ROM" Command LCALL WRITE_BYTE MOV A,#048H ;"COPY SCRATCHPAD" Command LCALL WRITE_BYTE LCALL OW_RESET RET ;********************************** WRITE_BYTE: MOV GenLC,#8 W_LOOP: RRC A CLR DQ MOV DlyFactor,#3 ; \ Takes approximately 7us WL0: DJNZ DlyFactor,WL0 ; / MOV DQ,C MOV DlyFactor,#3 ;60us LCALL DELAY15 SETB DQ MOV DlyFactor,#5 ; \ Takes approximately 10us WL1: DJNZ DlyFactor,WL1 ; / DJNZ GenLC,W_LOOP RET ;********************************** READ_BYTE: CLR A MOV GenLC,#8 R_LOOP: CLR DQ NOP NOP NOP NOP SETB DQ MOV DlyFactor,#3 ; \ Takes approximately 7us RL0: DJNZ DlyFactor,RL0 ; / MOV C,DQ RRC A MOV DlyFactor,#3 ;60us LCALL DELAY15 SETB DQ MOV DlyFactor,#5 ; \ Takes approximately 10us RL1: DJNZ DlyFactor,RL1 ; / DJNZ GenLC,R_LOOP RET ;********************************** OW_RESET: CLR DQ MOV DlyFactor,#31 LCALL DELAY15 SETB DQ MOV DlyFactor,#4 LCALL DELAY15 CLR F0 ;F0 is a general purpose flag in PSW used here for sampling "presence pulse" JB DQ,NoPulse SETB F0 NoPulse:MOV DlyFactor,#27 LCALL DELAY15 RET ;********************************** LCD_INIT:MOV LCDBUF,#00000001B ACALL LCD_CMD_WR MOV LCDBUF,#00111000B ;8bit,5x7,2-line (note:some 1x16 LCDs are configured logically as 2*8!) ACALL LCD_CMD_WR MOV LCDBUF,#00001100B ACALL LCD_CMD_WR MOV LCDBUF,#00000110B ACALL LCD_CMD_WR RET ;********************************** LCD_CMD_WR: CLR RS MOV P2,LCDBUF SETB EN MOV DlyFactor,#200 LCALL DELAY15 CLR EN RET ;********************************** LCD_DATA_WR: SETB RS MOV P2,LCDBUF SETB EN MOV DlyFactor,#200 LCALL DELAY15 CLR EN RET ;********************************** DELAY15: ;This subroutine suspends CPU for (DlyFactor x 15) + 15 us MOV DlyLC,#5 L0: DJNZ DlyLC,L0 L1: MOV DlyLC,#6 L2: DJNZ DlyLC,L2 DJNZ DlyFactor,L1 RET ;********************************** TIMESTR:DB '00|00:00',0 AIRSTR: DB '| ? ?',0 TESTSTR:DB 'Test < > ',0 END