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

📄 d9999.asm

📁 学林电子实验箱源码 完整板
💻 ASM
字号:
 ;可预制的倒计时钟,2位显示 p34个位调整p35十位调整 p32启动!
;***************************************************************************
;*  sxj1974@163.com		     (51c51 test web)     www.8951.com     *
;*  Create by :石学军      www.51c51.com 更多例程请登陆网站        	   *
;***************************************************************************
 
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.5    	;第一个数码管控制
second    bit p2.6    	;第二个数码管控制
tmrvar    equ 60110   	;定时器的初值65536-5000
hidden    equ 0ffh     	;显示器的消隐
    org 0000h
    jmp start
    org 1*8+3          	;time0中断入口
    jmp int_t0          ;到定时器t0中断服务程序的入口
start:
      mov sp,#5fh       ;设置堆栈
      mov p1,#0ffh      ;所有led熄灭
      mov setval,#59    ;初值59
      mov value,setval  ;开始不运行,按键后运行
      clr startrun
      clr keyok          ;清除有键按下的标志
      mov tmod,#01h
    mov th0,#HIGH(TMRVAR) ;取tirvar的高8位
    MOV TL0,#LOW(TMRVAR)  ;取tirvar的低8位
    SETB ET0           	  ;开t0中断
    SETB TR0              ;定时器开始运行
  
    SETB EA            	  ;开总中断
LOOP:CALL KEY             ;调用键盘程序
   JB KEYOK,KEYPROC       ;如果有键盘按下则转键盘处理
NEXT:MOV A,VALUE           ;获得秒的数值
         MOV B,#10
         DIV AB            ;二进制转10进制10位个位分别送显示缓冲
NEXT1:MOV DISPBUF,A        ;
      MOV DISPBUF+1,B      ;个位送显示缓冲
      JMP LOOP
KEYPROC:MOV A,KEYVAL       ;取得键值
        JZ KEYRUN          ;如果为0转keyrun
        DEC A
        JZ KEYSTOP         ;如果键值1 转stop
        DEC A

        JZ KEYLEFT         ;如果键值2转left
        JMP KEYRIGHT       ; 如果为3转right
KEYRUN:
       SETB STARTRUN       ; 将开始运行的标志送1
       JMP LOOP
KEYSTOP:
        CLR STARTRUN       ;开始运行位送0
        JMP LOOP
KEYLEFT:                   ;键盘处理,10位加1并在0-5循环
        CLR STARTRUN       ;先停止秒
        MOV A,SETVAL      ;取设置位
        ADD A,#10          ;加10
        CJNE A,#60,LEFT0   ;到60了么?
        MOV A,#0          ;是则清零
        JMP LEFT2         ;转left2
LEFT0:JNC LEFT1            ;比60大么, 是则转left1
      JMP LEFT2            ; 转left2
LEFT1:SUBB A,#60           ;减60
LEFT2:MOV SETVAL,A         ;处理后的a送回setval
          MOV VALUE,SETVAL ;送显示
          JMP LOOP
KEYRIGHT:                  ;键盘处理,10位加1并在0-5循环
         CLR STARTRUN      ;先停止秒
         INC DISPBUF+1     ;显示器的低位加1
         MOV A,DISPBUF+1   ; 送到a
         CJNE A,#10,REFT0  ;与10比较不等于则转移
         MOV DISPBUF+1,#0  ;等于10则送0
REFT0:MOV A,DISPBUF        ; 取出显示缓冲的高位
          MOV B,#10
          MUL AB                ;乘10
          ADD A,DISPBUF+1       ;加低位
          MOV SETVAL,A          ;送到setval暂存
          MOV VALUE,SETVAL      ;送显示
          JMP LOOP
KEY: ORL P3,#00111100B         ;键盘口先送1
     CLR KEYOK                 ;清key标志
     MOV A,P3                  ;取p3的值
     ORL A,#11000011B          ;把无关的4位置位
     CPL A                     ;取反a
     JZ KEY_RET                ;没有按则所有位都是1 取反则为0
     CALL DELAY

     MOV A,P3                  ;再读p3的值
     ORL A,#11000011B
     CPL A
    JZ KEY_RET
    SETB KEYOK                 ;确实有按下
    JNB ACC.2,KEY_1            ; s1没有按转key1
    MOV KEYVAL,#0              ;如按下则值为0
    JMP KEY_RET
KEY_1:JNB ACC.3,KEY_2          ;s1没有按转key2
          MOV KEYVAL,#1        ;如按下则值为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: mov r5,#2		;延时20MS
	d1:mov r6,#2

	D2:djnz r6,d2
	djnz r5,d1
	ret

INT_T0:     			;定时器t0的中断响应
       PUSH ACC
       PUSH PSW    		;压堆栈
       MOV TH0,#HIGH(TMRVAR)
       MOV TL0,#LOW(TMRVAR)
       INC COUNT     		;软件计数器加1
       MOV A,COUNT   	         ;
       CJNE A,#200,INT_N2
       MOV COUNT,#0         	;到了200清除
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       ;字型表的首地址
       MOVC A,@A+DPTR
       MOV P0,A           	; 送显示
       MOV A,COUNTER      	 ;取计数器的值
       JZ DISPFIRST       	;  如果为0则显示第一位
       CLR SECOND           	; 否则显示第二位
       AJMP DISPNEXT
DISPFIRST:
CLR FIRST                   	;显示第一位
DISPNEXT:
         INC COUNTER         	;计数器加1
         MOV A,COUNTER
         DEC A
         DEC A               	;如果为2则回0
         JZ RSTCOUNT
         AJMP DISPEXIT
RSTCOUNT:
         MOV COUNTER,#0      	;计数器的值只能为0或者1
DISPEXIT:
         POP PSW
         POP ACC
RETI
DISPTAB:DB   28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H

END






⌨️ 快捷键说明

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