OpenVINOTM,给你看得见的未来!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 精确到1%秒的单片机计时器汇编程序

共1条 1/1 1 跳转至

精确到1%秒的单片机计时器汇编程序

助工
2014-10-05 20:19:51    评分
程序效果:利用单片机的定时/计数器设计一个计时器,
 按key0后启动,要求精确显示到百分之一秒。
发挥部分:   
1:定时结束后有提示音报警,并可重新定时
2:定时时间可设置,最多30s
3:定时过程中可暂停
4:按下key1暂停计时,并记下此刻数值
5:按下key2显示第一次按下key1的数值(按下第一次有效,其它均无效)
3:本程序版权所有:51hei.com.
*/
 ORG 0000H
 LJMP START   //主程序必须避开地址000BH
 ORG 000BH  //定时器0的中段服务程序,起始地址为000BH
 LJMP IT00
 ORG 0030H
START:    MOV TH0,#0EBH //装入初始值,定时时间为10ms
 MOV TL0,#64H
 MOV TMOD,#01H //工作方式1
 MOV 40H,#00
 MOV 41H,#00
 MOV 42H,#00
 MOV 43H,#00
 MOV 33H,#00   //显示初值为0
 MOV 32H,#00
 MOV 31H,#00
 MOV 30H,#00
 MOV R1,#00
 MOV R2,#00
 SETB ET0   //打开定时0
 SETB EA   //开总中断
HERE:    JNB P3.4,KEY0  //扫描是否有按键按下
 JNB P3.5,KEY1
 JNB P3.6,KEY2
 LCALL DISPLAY  //此处是为了防止掉显
 LJMP HERE

KEY0:    LCALL DELAY1  //延时10ms
 JB P3.4,HERE  //判断key0是否真的按下去了
LKOP:      LCALL DISPLAY //真的按下去了
 JNB P3.4, LKOP //检查是否松手,没有则继续循环,别忘了要显示
 MOV A,R2   
 CJNE A,#01,LSP //判断key2 是否按下去过(只能按一次)


 MOV R2,#00  //清零


 MOV 30H,34H  //真的按下去了
 MOV 31H,35H  //显示key2按下前的值
 MOV 32H,36H
 MOV 33H,37H
LSP:        SETB TR0 //启动定时器
 LJMP HERE


KEY1:      LCALL DELAY1 //显示消抖
 JB P3.5,HERE
 CLR  TR0  //关闭定时器
LKOP1:    LCALL DISPLAY
 JNB  P3.5,LKOP1
 INC R1
 MOV A,R1
LEP:        CJNE A,#01,HERE  //判断key2是否按下(只能按一次)
 MOV 40H,30H  //暂存key2按下去前的值
 MOV 41H,31H
 MOV 42H,32H
 MOV 43H,33H
 LJMP HERE


KEY2:      LCALL DELAY1
 JB P3.6,HERE
 CLR TR0
LKOP2:    LCALL DISPLAY
 JNB  P3.6,LKOP2
 INC R2  //加1,为标志,用于判断key2是否按下去了
 MOV A,R2  //此处写的是一个通用形式,只暂存一个数值
LEP2:      CJNE A,#01,HERE  //此语句大可不写
 MOV 34H,30H    
 MOV 35H,31H //保存码表当时的数值,便于回复到原值
 MOV 36H,32H
 MOV 37H,33H


 MOV 30H,40H   //保存key1第一次按下的数值
 MOV 31H,41H
 MOV 32H,42H
 MOV 33H,43H
 LJMP HERE
  
//每10ms加1子程序
ADD1:      INC 30H     //百分位减1
 MOV A,30H
 CJNE A,#00AH,LOOP2 //判断百分位减到0之后是否再减1
 MOV 30H,#00   //是,装入初值9
 INC 31H    //十分位减1
 MOV A,31H
 CJNE A,#0AH,LOOP2 //判断百分位减到0之后是否再减1
 MOV 31H,#00
 INC 32H
 MOV A,32H
 CJNE A,#0AH,LOOP2
 MOV 32H,#00
 INC 33H
 MOV A,33H
 CJNE A,#0AH,LOOP2
 MOV 33H,#00
 SETB P2.0  //关闭蜂鸣器  
 LCALL DELAY   //延时
 LCALL DELAY
  CLR P2.0    //从15s减到0s后,驱动蜂鸣器
 MOV 33H,#00   //装入初值15s
 MOV 32H,#00
 MOV 31H,#00
 MOV 30H,#00
 CLR TR0   //关闭定时器,
LP1:         JB P3.4,LP //判断KEY0是否按下
 SETB TR0 //按下,则启动定时器 ,这里我没有消抖
 SJMP LOOP2
LP:  LCALL  DISPLAY  //没有按下,调用显示,防止掉显
 SJMP LP1
LOOP2:    NOP    //空指令
 RET    //返回
//显示子程序
DISPLAY: MOV DPTR,#TAB  //赋表首地址
 MOV A,#0FBH   
 MOV P2,A  //亮最左边的数码管
 XCH A,R0   //暂存A的值
 MOV A,33H
 MOVC A,@A+DPTR //根据表值查找所需的值
 MOV P0,A  //显示值
 LCALL DELAY   //延时
 XCH A,R0 //恢复原值
 RL A    //循环左移,为下次做准备


 MOV P2,A
 XCH A,R0
 MOV A,32H
 MOVC A,@A+DPTR
 MOV P0,A
 LCALL DELAY
 XCH A,R0
 RL A


 MOV P2,A
 XCH A,R0
 MOV A,31H
 MOVC A,@A+DPTR
 MOV P0,A
 LCALL DELAY
 XCH A,R0
 RL A


 MOV P2,A
 XCH A,R0
 MOV A,30H
 MOVC A,@A+DPTR
 MOV P0,A
 LCALL DELAY
 RET
TAB:     DB 3FH,06H,5BH,4FH,66H  ;数码管显示的数值   
 DB  6DH,7DH,07H,7FH,6FH    
IT00:     MOV TH0,#0EBH  //装入初值,时间为10ms
 MOV TL0,#64H
 LCALL ADD1   //减10ms
 RETI     //返回
DELAY:    MOV R7,#04 //延时子程序,时间大约为:2us*4*250
DEL2:       MOV R6,#250
DEL1:       DJNZ R6,DEL1
 DJNZ R7,DEL2
 RET
DELAY1:  MOV R5,#20
DEL3:    MOV R4,#250
DEL4:      DJNZ R4,DEL4
    DJNZ R5,DEL3
 RET
 END  //结束


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]