搜索
热搜: ROHM 模拟 车载
查看: 1406|回复: 3

[分享] 如何利用单片机设计一个计时器

  [复制链接]

该用户从未签到

1347

主题

6657

帖子

0

精华

论坛元老

最后登录
2020-7-26
发表于 2020-3-31 09:36:30 | 显示全部楼层 |阅读模式
程序效果:利用单片机的定时/计数器设计一个计时器,按key0后启动,要求精确显示到百分之一秒。

        发挥部分:

        1:定时结束后有提示音报警,并可重新定时

        2:定时时间可设置,最多30s

        3:定时过程中可暂停

        4:按下key1暂停计时,并记下此刻数值

        5:按下key2显示第一次按下key1的数值(按下第一次有效,其它均无效)

        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 //扫描是否有按键按下


回复

使用道具 举报

该用户从未签到

1347

主题

6657

帖子

0

精华

论坛元老

最后登录
2020-7-26
 楼主| 发表于 2020-3-31 09:37:04 | 显示全部楼层
        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 //结束
回复 支持 反对

使用道具 举报

该用户从未签到

2384

主题

9837

帖子

0

精华

论坛元老

最后登录
2024-4-23
发表于 2020-4-1 12:49:14 | 显示全部楼层
学习学习如何利用单片机设计一个计时器
回复 支持 反对

使用道具 举报

该用户从未签到

1347

主题

6657

帖子

0

精华

论坛元老

最后登录
2020-7-26
 楼主| 发表于 2020-4-2 08:58:17 | 显示全部楼层
shakencity 发表于 2020-4-1 12:49
学习学习如何利用单片机设计一个计时器

那你多学习学习 luomu.png
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条

Archiver|手机版|小黑屋|罗姆半导体技术社区

GMT+8, 2024-4-25 22:58 , Processed in 0.099266 second(s), 15 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表