定时插座程序(终稿) ;************************************************************** ;电院 定时插座 ;by 夜空守望者 ;2009-6-4 ;************************************************************** ;功能描述:带键盘设置的时间计数器 ;功能:实现1分钟到99小时99分钟内的定时。可定时关机或定时开机。 ;各个键的功能: ;S1:小时十位调整 ;S2:小时个位调整 ;S3;分钟十位调整 ;S4:分钟各位调整 ;可扩展功能:时间显示 ;硬件描述: ;P0口显示字段。P2.0-2.3共阳数码管控制端。P1.0-P1.3按键 ;P3.4继电器控制端 ;************************************************************** STARTRUN BIT 01H;开始运行标志 KEYOK BIT 00H;有键按下标志 SCOUNT EQU 21H;分计数器 SETVAL EQU 22H;预置分值储存单元 SCOUNT2 EQU 26H;小时计数器 SETVAL2 EQU 27H;预置小时储存单元 TCOUNT EQU 24H;;秒计数器 TCOUNTER EQU 250;软件计数器的计数值,X定时器4MS等于1S KEYVAL EQU 25H;键值储存单元 DISPBUF EQU 58H;显示缓冲区 COUNTER EQU 57H;计数器,显示程序通过它得知现在正在显示的数码管 TMRVAR EQU 61536;设定4MS。65536-4000定时器初值 ORG 0000H JMP START ORG 0*8+3;INTO中断入口 RETI ORG 1*8+3;定时器0中断入口 LJMP INT_T0 ORG 2*8+3 RETI ORG 3*8+3 RETI ORG 4*8+3 RETI ;*******************主程序设定************************************ START: CLR P3.5;关定时开机指示灯 MOV R1,#0 START1: CJNE R1,#0,KAIGUAN;若R1不等于0,则转移 SETB P3.4;关继电器 JMP GUANJI KAIGUAN: CLR P3.4;开继电器 CLR P3.6;关定时关机指示 GUANJI: MOV R7,#60;用于分循环 MOV R4,#60;用于小时循环 MOV SP,#5FH;初始化堆栈 MOV SCOUNT,#0 MOV SCOUNT2,#0 MOV SETVAL,#00;启动程序默认值为0 MOV SETVAL2,#00 MOV SCOUNT,SETVAL MOV SCOUNT2,SETVAL2 CLR KEYOK CLR STARTRUN CALL INIT_T0 SETB EA ;********************主程序开始*************************************** LOOP: CALL KEY;调用键盘程序 JB KEYOK,KEYPROC;如果有键按下,转键盘处理程序 NEXT: MOV A,SCOUNT;获取分的数值 MOV B,#10 DIV AB NEXT1: MOV DISPBUF+2,A;送显示缓冲区 MOV DISPBUF+3,B NEXT2: MOV A,SCOUNT2;获取小时的数值 MOV B,#10 DIV AB NEXT3: MOV DISPBUF,A MOV DISPBUF+1,B JMP LOOP ;*******************键值处理程序**************************************** KEYPROC: MOV A,KEYVAL;取得键值 JZ KEY1;如果键值是0,转 DEC A JZ KEY2;如果键值是1,转 DEC A JZ KEY3;如果键值是2,转 DEC A JZ KEY4;如果键值是3,转 JMP KEY5; KEY1:;对小时十位进行操作 INC DISPBUF;将显示缓冲区的数加1 MOV A,DISPBUF CJNE A,#9,EFT01 MOV DISPBUF,#0 SETB STARTRUN EFT01:;键值处理 MOV B,#10 MUL AB ADD A,DISPBUF+1 MOV SETVAL2,A MOV SCOUNT2,SETVAL2 SETB STARTRUN JMP LOOP KEY2: INC DISPBUF+1 MOV A,DISPBUF+1 CJNE A,#10,EFT02 MOV DISPBUF+1,#0 SETB STARTRUN EFT02: MOV A,DISPBUF MOV B,#10 MUL AB ADD A,DISPBUF+1 MOV SETVAL2,A MOV SCOUNT2,SETVAL2 SETB STARTRUN JMP LOOP KEY3: INC DISPBUF+2 MOV A,DISPBUF+2 CJNE A,#6,LEFT0 MOV A,#0 SETB STARTRUN LEFT0: MOV B,#10 MUL AB ADD A,DISPBUF+3 MOV SETVAL,A MOV SCOUNT,SETVAL SETB STARTRUN JMP LOOP KEY4: INC DISPBUF+3 MOV A,DISPBUF+3 CJNE A,#10,REFT0 MOV DISPBUF+3,#0 SETB STARTRUN REFT0: MOV A,DISPBUF+2 MOV B,#10 MUL AB ADD A,DISPBUF+3 MOV SETVAL,A MOV SCOUNT,SETVAL SETB STARTRUN JMP LOOP KEY5: MOV R1,#1; SETB P3.5 CLR STARTRUN JMP START1 ;**************键盘程序******************************************************** KEY: MOV P1,#0FFH CLR KEYOK MOV A,P1 ORL A,#10110000B CPL A JZ KEY_RET CALL DELAY MOV A,P1 ORL A,#10110000B CPL A JZ KEY_RET SETB KEYOK JNB ACC.0,KEY_1 MOV KEYVAL,#0 JMP KEY_RET KEY_1: JNB ACC.1,KEY_2 MOV KEYVAL,#1 JMP KEY_RET KEY_2: JNB ACC.2,KEY_3 MOV KEYVAL,#2 JMP KEY_RET KEY_3: JNB ACC.3,KEY_4 MOV KEYVAL,#3 JMP KEY_RET KEY_4: MOV KEYVAL,#4 KEY_RET: MOV A,P1 ORL A,#11110000B CPL A JNZ KEY_RET RET ;****************************延时程序**************************** DELAY: PUSH PSW SETB RS0 MOV R7,#50 D1: MOV R6,#10 D2: DJNZ R6,D2 DJNZ R7,D1 POP PSW RET ;********************************************************************* INIT_T0: MOV TMOD,#01H MOV TH0,#HIGH(TMRVAR) MOV TL0,#LOW(TMRVAR) SETB ET0;开T0中断 SETB TR0;定时器T0开始运行 RET ;*******************************中断程序********************************* INT_T0: PUSH ACC PUSH PSW MOV TH0,#HIGH(TMRVAR);重新装入初值 MOV TL0,#LOW(TMRVAR) AAA: INC TCOUNT ;软件计数器加1 MOV A,TCOUNT CJNE A,#TCOUNTER,INT_N2;判断是否等于250,即是否计数到1秒。 CPL P2.6;P2.6接发光二极管,实现每秒闪光 MOV TCOUNT,#0 JNB STARTRUN,INT_N2;若等于0,转移。即是否开始运行 DJNZ R7,AAA;实现分计数,循环60次。1S乘以60. MOV R7,#60 MOV A,SCOUNT2 CJNE A,#0,BBB;若小时计数器不为0,转 JMP EEE BBB: MOV A,SCOUNT CJNE A,#0,EEE;若分计数器不为0,转 LJMP CCC EEE: DEC SCOUNT;分计数器减1 MOV A,SCOUNT JNZ INT_N2;若不为0,转到显示程序 MOV A,SCOUNT2 JNZ CCC JMP DDD CCC: DEC SCOUNT2;小时计数器减1 MOV SCOUNT,#59;分计数器装载59 JMP INT_N2;转显示程序 ;**************************报警,控制继电器程序************************************** DDD: MOV R6,#10 LOOP4: CPL P3.7;接蜂鸣 CPL P3.6 CPL P3.5 MOV R5,#200 LOOP3:LCALL DELAY DJNZ R5,LOOP3 DJNZ R6,LOOP4 CPL P3.4;继电器端口取反 PPP:CLR P3.6 CLR P3.5 LJMP $ ;**************************************显示程序************************************88 INT_N2: ORL P2,#00001111B;关所有显示器 MOV A,Counter;取计数器值 MOV DPTR,#BitTab;将位码地址送到DPTR MOVC A,@A+DPTR ANL P2,A;送位码 JNB ACC.1,XIAOSHUDIAN;是否显示第二位。是则转,加小数点处理。 MOV A,#DISPBUF ADD A,Counter MOV R0,A MOV A,@R0 MOV DPTR,#DISPTAB MOVC A,@A+DPTR MOV P0,A;送段码 LJMP SSS XIAOSHUDIAN: MOV A,#DISPBUF+1 MOV R0,A MOV A,@R0 MOV DPTR,#DISPTAB MOVC A,@A+DPTR CLR C SUBB A,#80H MOV P0,A;送段码 SSS: INC Counter MOV A,Counter CJNE A,#4,DISPEXIT;如果计数器为4,让它回0 MOV Counter,#0 DISPEXIT: POP PSW POP ACC RETI DISPTAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;0到9的码字 BitTAb: DB 0FEH,0FDH,0FBH,0F7H;位码 END