×
单片机 > 单片机程序设计 > 详情

秒计时器程序

发布时间:2020-05-29 发布时间:
|

;************************************************** 
;带键盘设置的秒计时器 
;功能:倒计时的秒计时器,从59倒计到0,然后又从59开始倒计到0; 
;各个键的功能 
;S1:开始运行 
;S2:停止运行 
;S3:高位加1,按一次,数码管的十位加1,从0-5循环变化 
;S4:低位加1,按一次,数码管的个位加1,从0-9循环变化

;************************************************** 
KEYOK BIT  00H 
STARTRUN BIT 01H 
VALUE EQU 21H 
SETVAL EQU 22H ;设置值 
COUNTER EQU 23H ;用于显示的计数器 
COUNT EQU 24H ;秒计数器 
KEYVAL EQU 25H 
DISPBUF EQU 5EH 
FIRST BIT P2.7 ;第一位数码管的位控制 
SECOND BIT P2.6 ;第二位数码管的位控制 
P1LED EQU 22H 
TMRVAR EQU 60110 ;65536-5000*12/11.0592 定时器初值5毫秒 

ORG 0000H  
JMP START 
ORG 0*8+3 ;INT0中断入口 
RETI 
ORG 1*8+3 ;TIMER0中断入口 
JMP INT_T0 ;转去定时器0中断服务程序入口 
ORG 2*8+3 ;INT1中断入口 
RETI 
ORG 3*8+3 ;TIMER1中断入口 
RETI 
ORG 4*8+3 ;串行中断入口 
RETI 
START: 
MOV  SP,#5FH 
MOV  P1,#0FFH ;所有LED全部熄灭 
MOV  VALUE,#0 
MOV  P1LED,#0FEH 
MOV  SETVAL,#59  
MOV  VALUE,SETVAL 
MOV  DISPBUF,#5 
MOV  DISPBUF+1,#9 
CLR STARTRUN 
CLR KEYOK 
CALL INIT_T0 
SETB EA 
LOOP:  
CALL KEY ;调用键盘程序 
JB KEYOK,KEYPROC ;如果有键按下,转键盘处理 
NEXT:  
MOV  A,VALUE ;获得秒的数值 
MOV  B,#10  
DIV AB ;二进制转化为十进制,十位和个位分送显示缓冲区 
NEXT1:  
MOV  DISPBUF,A 
MOV  DISPBUF+1,B ;个位送显示缓冲区 
JMP LOOP 
;以下是键值处理 
KEYPROC: 
MOV  A,KEYVAL ;取得键值 
JZ KEYRUN ;如果键值是0 
DEC A 
JZ KEYSTOP ;如果键值是1 
DEC A 
JZ KEYLEFT ;如果键值是2 
JMP KEYRIGHT ;键值是3,转 
KEYRUN:  
SETB STARTRUN 
JMP LOOP 
KEYSTOP: 
CLR STARTRUN 
JMP LOOP 
KEYLEFT: 
CLR STARTRUN 
INC DISPBUF 
MOV  A,DISPBUF 
CJNE A,#6,LEFT0 
MOV  A,#0 
LEFT0:  
MOV  B,#10 
MUL AB 
MOV  SETVAL,A 
MOV  VALUE,SETVAL 
JMP LOOP 
KEYRIGHT: 
CLR STARTRUN 
INC DISPBUF+1 
MOV  A,DISPBUF+1 
CJNE A,#10,REFT0 
MOV  DISPBUF+1,#0 
REFT0:  
MOV  A,DISPBUF 
MOV  B,#10 
MUL AB 
ADD A,DISPBUF+1 
MOV  SETVAL,A  
MOV  VALUE,SETVAL 
JMP LOOP 
;键盘程序 
KEY:  
MOV  P3,#0FFH 
CLR KEYOK  
MOV  A,P3 
ORL A,#11000011B 
CPL A 
JZ KEY_RET 
CALL DELAY 
MOV  A,P3 
ORL A,#11000011B 
CPL A 
JZ KEY_RET 
SETB KEYOK 
JNB ACC.2,KEY_1 ;S1没有按下,转 
MOV  KEYVAL,#0 
JMP KEY_RET 
KEY_1:  
JNB ACC.3,KEY_2 ;S2没有按下,转 
MOV  KEYVAL,#1 
JMP KEY_RET 
KEY_2:  
JNB ACC.4,KEY_3 
MOV  KEYVAL,#2 
JMP KEY_RET 
KEY_3:  
MOV  KEYVAL,#3 
KEY_RET: 
MOV  A,P3 
ORL A,#11000011B 
CPL A 
JNZ KEY_RET 
RET 

DELAY: 
PUSH PSW 
SETB RS0 
MOV  R7,#50 
D1:  MOV  R6,#50 
D2: DJNZ R6,D2 
DJNZ R7,D1 
POP PSW 
RET 

INIT_T0: ;初始化T0为5毫秒的定时器 
MOV  TMOD,#01H 
MOV  TH0,#HIGH(TMRVAR) 
MOV  TL0,#LOW(TMRVAR) 
SETB ET0 ;开T0中断 
SETB TR0 ;定时器0开始运行 
RET ;返回 

;以下是中断程序,实现秒计数和显示 
INT_T0: ;定时器T0的中断响应程序 
PUSH ACC ;ACC入栈 
PUSH PSW ;PSW入栈 
MOV  TH0,#HIGH(TMRVAR) 
MOV  TL0,#LOW(TMRVAR) 
INC COUNT ;软件计数器加1 
MOV  A,COUNT 
CJNE A,#20,INT_N2 
MOV  COUNT,#0 ;计到20,软件计数器清0 
INT_N1:  
JNB STARTRUN,INT_N2 ;停止运行,转 
DEC VALUE ;计数器减1 
MOV  A,VALUE  
JNZ INT_N2 ;不等于0,转 
MOV  VALUE,SETVAL;否则,再置初值 
INT_N2: ;以下是显示部份 
SETB FIRST 
SETB SECOND ;关显示 
MOV  A,#DISPBUF ;显示缓冲区首地址 
ADD A,Counter  
MOV  R0,A 
MOV  A,@R0 ;根据计数器的值取相应的显示缓冲区的值 
MOV  DPTR,#DISPTAB ;字形表首地址 
MOV C A,@A+DPTR ;取字形码 
MOV  P0,A ;将字形码送P0位(段口) 
MOV  A,Counter ;取计数器的值 
JZ DISPFIRST ;如果是0则显示第一位 
CLR SECOND ;否则显示第二位 
AJMP DISPNEXT 
DISPFIRST: 
CLR FIRST ;显示第一位  
DISPNEXT: 
INC Counter ;计数器加1 
MOV  A,Counter 
DEC A ;如果计数器计到2,则让它回0 
DEC A  
JZ RSTCOUNT  
AJMP DISPEXIT 
RSTCOUNT: 
MOV  Counter,#0 ;计数器的值只能是0或1 
DISPEXIT:  
POP PSW 
POP ACC 
RETI 
DISPTAB: DB 28H,7EH,0a4H,64H,72H,61H,21H,7CH,20H,60H  
END 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯