单片机 按键秒表

单片机 按键秒表,第1张

秒表的设计程序

用89C51,外接晶振,复位电路,二个数码管,二个按键,做一个电子秒表,具体要求为用按键起停电子表,可用按键设计倒计时时间(如10S,20S,60S),并启动倒计时功能。能用按键选择以上两功能之一。

三、程序代码:

A_BIT EQU 20H 数码管个位数存放内存位置

B_BIT EQU 21H 数码管十位数存放内存位置

TEMP EQU 22H 计数器数值存放内存位置 开机初始化

MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入

MOV P0,#0FFH使显示时间数码管熄灭

CLR F0

CLR F1

MOV DPTR,#NUMTAB 指定查表启始地址

等待按键输入

根据按键的输入判断执行什么功能按键1按下则执行功能1

MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入

MOV P0,#0FFH使显示时间数码管熄灭

START:JB P3.6,START1循环判断开始按钮K1是否按下?

ACALL DELAY10延时10毫秒触点消抖

JB P3.6,START如果是干扰就返回

JNB P3.6,$等待按键松开

LJMP GN1 按键2按下则执行功能2START1: JB P3.7,START循环判断开始按钮K2是否按下?

ACALL DELAY10延时10毫秒触点消抖

JB P3.7,START1如果是干扰就返回

JNB P3.7,$

LJMP GN2数码管显示秒表时间的程序

GN1:先初始化

S1:MOV A,#0

MOV TEMP,A

GOON1: MOV R2,#2

JS1: MOV R3,#250

TIME1: MOV A,TEMP 将TEMP中的十六进制数转换成10进制

MOV B,#10 10进制/10=10进制

DIV AB

MOV B_BIT,A 十位在A

MOV A_BIT,B 个位在B LCALL DPLOP1插入一段判断定时过程中是否有按键输入的程序段

C1: JB P3.6,B1

ACALL DELAY10延时10毫秒消抖

JB P3.6,C1

JNB P3.6,$等待按键松开

CPL F0

ZT1: MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入

JB P3.6,$循环判断开始按钮K1是否按下?

ACALL DELAY10延时10毫秒触点消抖

JB P3.6,ZT1如果是干扰就返回

JNB P3.6,$等待按键松开

LCALL DPLOP1

B1: JB P3.7,LOOP1

ACALL DELAY10延时10毫秒消抖

JB P3.7,B1

JNB P3.7,$等待按键松开

AJMP OVERLOOP1: DJNZ R3,TIME1 2毫秒循环执行250次,时间约0.5秒

DJNZ R2,JS1 循环执行2次,时间为1 秒钟INC TEMP满一秒钟对时间加1

MOV A,TEMP

CLR C

SUBB A,#60

JNZ GOON1判断TEMP的数值是否为60?不为60循环

ACALL OVER

RET

GN2: MOV A,#14H 设定倒计时的时间20S

MOV TEMP,A数码管显示倒计时时间的程序

初始化

MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入

MOV P0,#14H使显示时间为设定的倒计时时间 GOON2: MOV R2,#2

JS2: MOV R3,#250

TIME2: MOV A,TEMP 将TEMP中的十六进制数转换成10进制

MOV B,#10 10进制/10=10进制

DIV AB

MOV B_BIT,A 十位在A

MOV A_BIT,B 个位在BMOV DPTR,#NUMTAB 指定查表启始地址

DPLOP2: MOV A,A_BIT 取个位数

MOVC A,@A+DPTR 查个位数的7段代码

MOV P0,A 送出个位的7段代码

CLR P2.5 开个位显示

ACALL DELY1显示1毫秒

SETB P2.5关闭个位显示,防止鬼影

MOV A,B_BIT 取十位数

MOVC A,@A+DPTR 查十位数的7段代码

MOV P0,A 送出十位的7段代码

CLR P2.6 开十位显示

ACALL DELY1显示1毫秒

SETB P2.6关闭十位显示,防止鬼影插入一段判断定时过程中是否有按键输入的程序段

C2: JB P3.6,B2

ACALL DELAY10延时10毫秒消抖

JB P3.6,C2

JNB P3.6,$等待按键松开

ZT2:MOV P3,#0FFH对P3口初始化,设置为高电平,用于按键输入

JB P3.6,$循环判断开始按钮K1是否按下?

ACALL DELAY10延时10毫秒触点消抖

JB P3.6,ZT2如果是干扰就返回

JNB P3.6,$等待按键松开

B2: JB P3.7,LOOP2

ACALL DELAY10延时10毫秒消抖

JB P3.7,B1

JNB P3.7,$等待按键松开

AJMP OVERLOOP2: DJNZ R3,TIME2 2毫秒循环执行250次,时间约0.5秒

DJNZ R2,JS2 循环执行2次,时间为1 秒钟DEC TEMP满一秒钟对时间减1

MOV A,TEMP

JNZ GOON2判断TEMP的数值是否为0?不为0循环

ACALL OVER

RET

结束定时

OVER: AJMP START退到开机初始化状态1毫秒延时子程序

DELY1: MOV R4,#2

D1:MOV R5,#248

DJNZ R5,$

DJNZ R4,D1

RET10毫秒延时子程序

DELAY10: MOV R4,#20

D2:MOV R5,#248

DJNZ R5,$

DJNZ R4,D2

RET实验板上的两位一体的数码管0~9各数字的显示代码

NUMTAB: DB 40H,79H,24H,30H,19H,12H,02H,78H,00H,10H

DPLOP1: MOV A,A_BIT 取个位数

MOVC A,@A+DPTR 查个位数的7段代码

MOV P0,A 送出个位的7段代码

CLR P2.5 开个位显示

ACALL DELY1显示1毫秒

SETB P2.5关闭个位显示,防止鬼影

MOV A,B_BIT 取十位数

MOVC A,@A+DPTR 查十位数的7段代码

MOV P0,A 送出十位的7段代码

CLR P2.6 开十位显示

ACALL DELY1显示1毫秒

SETB P2.6关闭十位显示,防止鬼影

RET

END

用到time.h文件

里面有个clock()函数,返回一个clock_t类型的数字,表示从程序运行开始,CPU的"滴答"数

而在time.h里有个常量CLOCKS_PER_SEC表示每秒钟有多少个"滴答".

这样,(((float)clock())/CLOCKS_PER_SEC)*1000这样的表达式就能得到从程序运行开始到现在的经过的时间.

程序的大致思路是这样的,程序按下1的时候记下当时的程序运行时间.

从这时起,每时刻捡取程序运行时间,然后减去先前的值,就可以得到已经计时的时间了.

只要让用户按下0结束计时就好了

在conio.h文件里,有个函数kbhit()是个非阻塞函数,用来检查键盘缓冲里有没有按键按下,若有,则返回1,若没有,则返回0,以此来作为判断,若返回1,则捡取按键,测试它是不是0或者1,若返回0,则表示用户没有动作,继续原来的工作,即继续计时或等待命令.

S_SEG SEGMENT STACK

DB 256 DUP(?)

S_SEG ENDS

D_SEG SEGMENT

COUNT DB 0 计时单元,初值为0

TENM DB ‘ 0’ 10分计时单元,初值为0

MINUTE DB ‘0:’ 分计时单元,初值为0

TENS DB ‘0’ 10秒计时单元,初值为0

SECOND DB ‘0.’ 秒计时单元,初值为0

HAOM DB ‘0’ 10毫秒计时单元,初值为0

HAO DB ’8’,’$’ 毫秒计时单元,初值为8

D_SEG ENDS

C_SEG SEGMENT

ASSUME CS:C_SEG ,SS:S_SEG

START: MOV AX,D_SEG

MOV DS,AX

CLI 先关中断,以获得INT1CH

MOV AX,351CH 调用35H号系统功能

INT 21H 返回ES:BX=中断向量(段:偏移)

PUSH BX 栈中保存INT1CH原中断向量

PUSH ES

STI 开中断,以使键盘工作

MOV AH,1 等待键按下

INT 16H

CLI 关中断

MOV DX,SEG TIMER 置新中断向量

MOV DS,DX

MOV DX,OFFSET TIMER DS:DX=新中断向量(段:偏移)

MOV AX,251CH

INT 21H

STI 再开中断,以使键盘和INT1CH工作

CHECK: MOV AH ,1 检查有无键代码

INT 16H

JZ DISPLAY1 无码可读,就跳转显示(DISPLAY系统保留)]

MOV AH ,0 无码可读,就要读取它

INT 16H

CMP AL ,51H 是’Q’吗

JE OVER 是,返回DOS

DISPLAY1: MOV AX,D_SEG 不是,就显示

MOV DS ,AX

ASSUME DS:D_SEG

LEA DX ,TENM DS:DX=显示字符串地址

MOV AH ,9 显示 mm :ss.msms

INT 21H

JMP CHECK 返回CHECK,循环继续

OVER: CLI

POP DS 由栈中取回INT1CH原向量

POP DX

MOV AX ,251CH 设置INT1CH,恢复原向量

INT 21H

STI 开中断

MOV AX ,4C00H 返回DOS

INT 21H

以下为使用INT 1CH的中断服务子程序

TIMER PROC FAR

PUSH AX

MOV AX , D_SEG

MOV DS , AX

ASSUME DS :D_SEG

INC COUNT 计时单元增1

CMP COUNT , ‘2’ 到110毫秒否

JL EXIT 不到,则返回

MOV COUNT , ‘0’ 到,则计时单元清0

INC HAOM 10毫秒计时单元增1

CMP HAOM ,’9’ 到1秒否

JLE EXIT 不到,则返回

INC SECOND 到,则秒计时单元增1

MOV HAOM , ‘0’ 10毫秒计时单元清0

CMP SECOND ,‘9’ 到10秒否

JLE EXIT 不到,则返回

MOV SECOND ,‘0’ 到,则秒计时单元清0

INC TENS 10秒计时单元增1

CMP TENS ,‘6’ 到60秒否

JL EXIT 不到,则返回

MOV TENS ,‘0’ 到 ,则10秒计时单元清0

INC MINUTE 分计时单元清0

CMP MINUTE ,‘9’ 到10分 否

JLE EXIT 不到,则返回

MOV MINUTE ,‘0’ 到,则分计时单元清0

INC TENM 10分计时单元增1

CMP TENM ,‘6’ 到60分否

JL EXIT 不到,则返回

MOV TENM ,‘0’ 到,则10分计时单元清0,重新开始计时

EXIT: POP AX

IRET

TIMER ENDP

C_SEG ENDS

END START


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/7887432.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-11
下一篇2023-04-11

发表评论

登录后才能评论

评论列表(0条)

    保存