⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.rar.txt

📁 一个完整的计时器
💻 TXT
字号:
CODE_SEG        SEGMENT CODE
DATA_SEG        SEGMENT DATA
STACK_SEG SEGMENT IDATA
 RSEG  DATA_SEG
KEY_S:    DS   1
KEY_V:    DS   1
KEY_S1:    DS   1
KEY_V1:    DS   1
DIS_DIGIT:    DS   1
DIS_INDEX:    DS   1
SEC_BCD:    DS   8  ; 秒计数值, BCD码
KEY_TIMES:    DS   1  ; K1 按下次数
DIS_BUF:    DS   8  ; 显示缓冲区
 RSEG STACK_SEG
STACK:  DS 20
K1 BIT P3.2
K2 BIT P3.3
;===============================================================================
CSEG AT 0000H
 LJMP MAIN
CSEG AT 0000BH
 LJMP TIMER0
CSEG AT 0001BH
 LJMP TIMER1
 CSEG AT  0013H
 LJMP MAIN_LP2
;===============================================================================
 RSEG CODE_SEG
MAIN:
 USING 0
 MOV SP,#(STACK-1)
 MOV   P0,#0FFH  ; 初始化端口
 MOV   P2,#0FFH
 MOV   TMOD,#011H  ;
 MOV   TH1,#0DCH
 CLR   A
 MOV   TL1,A
 MOV   TH0,#0FEH
 MOV   TL0,#0BH
 LCALL CLR_TIME  ; 清零计时值
 MOV   DIS_DIGIT,#07FH  ; 上电时选通P27数码管
 CLR   A
 MOV   DIS_INDEX,A
 MOV   KEY_TIMES,A
 MOV   KEY_V,#01H 
 MOV   KEY_V1,#01H
 MOV   IE,#08EH  ; 使能timer0, timer1中断
 SETB  TR0
 CLR   TR1 
MAIN_LP:
 LCALL SCAN_KEY  ; 键扫描
 JZ   MAIN_LP   ; 无键返回
 MOV R7,#10   ; 延时10ms
 LCALL DELAYMS   ; 延时去抖动
 LCALL SCAN_KEY  ; 再次扫描
 JZ MAIN_LP   ; 无键返回 
 MOV   KEY_V,KEY_S  ; 保存键值
 LCALL PROC_KEY  ; 键处理
 SJMP MAIN_LP 
 
 MAIN_LP2:
 LCALL SCAN_KEY1 ; 键扫描
 JZ   MAIN_LP2   ; 无键返回 
 MOV R7,#10   ; 延时10ms
 LCALL DELAYMS   ; 延时去抖动
 LCALL SCAN_KEY1  ; 再次扫描
 JZ MAIN_LP2   ; 无键返回 
 MOV   KEY_V1,KEY_S1  ; 保存键值

 LCALL PROC_KEY3 ; 键处理

 RETI
;===============================================================================
CLR_TIME: 
 CLR   A
 MOV   SEC_BCD,A  ; 清零所有计时值
 MOV   SEC_BCD+01H,A
 MOV   SEC_BCD+02H,A
 MOV   SEC_BCD+03H,A
 MOV   SEC_BCD+04H,A
 MOV   SEC_BCD+05H,A
 MOV   SEC_BCD+06H,A
 MOV   SEC_BCD+07H,A
 LJMP  UPDATE_DISBUF  ; 更新显示缓冲区 
;===============================================================================
SCAN_KEY:
 CLR   A
 MOV   KEY_S,A
 MOV   C,K1   ; 读按键状态
 RLC   A
 ORL   KEY_S,A
 MOV   A,KEY_S
 XRL   A,KEY_V   ;  
 RET

  SCAN_KEY1:
 CLR   A
 MOV   KEY_S1,A
 MOV   C,K2   ; 读按键状态
 RLC   A
 ORL   KEY_S1,A
 MOV   A,KEY_S1
 XRL   A,KEY_V1   ;  
 RET 
;===============================================================================
PROC_KEY:
 MOV   A,KEY_V
 JB    ACC.0,END_PROC_KEY

 INC   KEY_TIMES
 MOV   A,KEY_TIMES
 CJNE  A,#01H,PROC_KEY1 
 SETB  TR1   ; KEY_TIMES = 1,第一次按下K1, 启动开始计时 
 RET 
PROC_KEY1:
   CLR   A

 ; KEY_TIMES = 2, 第二次按下K1, 停止计时 
 MOV KEY_TIMES ,A 
 
   CLR   TR1
 RET 
 END_PROC_KEY:
 RET 
PROC_KEY3:
  LCALL CLR_TIME  ; 第三次按下K1, 清零计时值 
 CLR   A
 MOV   KEY_TIMES,A  ; 清零KEY_TIMES 

RETI
   
;===============================================================================
TIMER0:
; 定时器0中断服程序, 用于数码管的动态扫描
; DIS_INDEX --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
; DIS_DIGIT --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
;  选通P2.0口数码管
; DIS_BUF   --- 显于缓冲区基地址  
 PUSH  ACC
 PUSH  PSW
 PUSH  AR0
 MOV   TH0,#0FCH
 MOV   TL0,#017H
 MOV   P2,#0FFH  ; 先关闭所有数码管
 MOV   A,#DIS_BUF  ; 获得显示缓冲区基地址
 ADD   A,DIS_INDEX  ; 获得偏移量
 MOV   R0,A   ; R0 = 基地址 + 偏移量
 MOV   A,@R0   ; 获得显示代码
 MOV   P0,A   ; 显示代码传送到P0口
 MOV   P2,DIS_DIGIT  ;
 MOV A,DIS_DIGIT  ; 位选通值右移(P20<-P27), 下次中断时选通下一位数码管
 RR A
 MOV DIS_DIGIT,A
 INC DIS_INDEX  ; DIS_INDEX加1, 下次中断时显示下一位
 ANL DIS_INDEX,#0x07  ; 当DIS_INDEX等于8(0000 1000)时, 清0
 POP   AR0
 POP   PSW
 POP   ACC 
 RETI 
;===============================================================================
TIMER1:
 PUSH  ACC
 PUSH  B
 PUSH  DPH
 PUSH  DPL
 PUSH PSW
 PUSH AR7
 ORL   TH1,#0DCH  ; 恢复定时器初值
 CLR   A
 MOV   R7,A 
 MOV   A,#LOW (SEC_BCD) 
 MOV   R0,A   ; 计时值寄存器地址到R0 
TIMER_INC:   ;  
 INC   @R0   ; 计时值加1
 MOV   A,@R0
 CLR   C
 SUBB  A,#10   ; 
 JC    END_INC   ; 如果低位不满10, 则结束
 MOV   @R0,#00H  ; 低位满10, 清零低位
 INC R0   ; 指向高位
 INC   R7   ;
 CJNE  R7,#08H,TIMER_INC ; 如果达到最高位, 则结束 
END_INC:
 LCALL UPDATE_DISBUF
 POP AR7 
 POP PSW
 POP   DPL
 POP   DPH
 POP   B
 POP   ACC
 RETI  
;===============================================================================
UPDATE_DISBUF:
; 根据计时寄存器的值更新显示缓冲区
 MOV   DPTR,#DIS_CODE  ; 保存表格地址
 MOV   A,sec_bcd
 MOV   DPTR,#dis_code
 MOVC  A,@A+DPTR  ; 获得显示代码
 MOV   dis_buf,A  ; 更新显示缓冲区
 MOV   A,sec_bcd+01H
 MOVC  A,@A+DPTR
 MOV   dis_buf+01H,A
 MOV   A,sec_bcd+02H
 MOVC  A,@A+DPTR
 ANL   A,#07FH   ; 显示小数点
 MOV   dis_buf+02H,A
 MOV   A,sec_bcd+03H
 MOVC  A,@A+DPTR
 MOV   dis_buf+03H,A
 MOV   A,sec_bcd+04H
 MOVC  A,@A+DPTR
 MOV   dis_buf+04H,A
 MOV   A,sec_bcd+05H
 MOVC  A,@A+DPTR
 MOV   dis_buf+05H,A
 MOV   A,sec_bcd+06H
 MOVC  A,@A+DPTR
 MOV   dis_buf+06H,A
 MOV   A,sec_bcd+07H
 MOVC  A,@A+DPTR
 MOV   dis_buf+07H,A
 RET   
; END OF UPDATE_DISBUF
;===============================================================================
DELAYMS:
; 延时子程序
; 传入参数:R7 --- 延时值(MS)
; 返回值:无
 MOV A,R7
 JZ END_DLYMS 
DLY_LP1:
 MOV R6,#185
DLY_LP2:
 NOP
 NOP
 NOP
 DJNZ R6,DLY_LP2
 DJNZ R7,DLY_LP1
END_DLYMS:
 RET
;===============================================================================
DIS_CODE:
db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h
 END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -