文档库 最新最全的文档下载
当前位置:文档库 › 单片机电子钟设计代码

单片机电子钟设计代码

;**************定义常用字符的ASC码*************
CR = 0DH ;回车键的ASCLL码
LF = 0AH ;换行键的ASCLL码
ESCKG = 1BH ;ESC键的ASCLL码
JIESHU = '$' ;定义"$"为字符串结束符
;**************下面为宏定义*******************
;******定义宏移动光标到指定位置*******
MOVTO MACRO ROW,LIE
PUSH AX
PUSH DX
MOV AH, 2
MOV DH, ROW ;行
MOV DL, LIE ;列
INT 10H
POP DX
POP AX
ENDM
;********定义宏输出指示符*******
GUANGBIAO MACRO
PUSH AX
PUSH BX
PUSH CX
MOV CX, 1
MOV AH, 9
MOV AL,'_'
MOV BL, 0FH
INT 10H
POP CX
POP BX
POP AX
ENDM
;******乘以10的宏*********
X10 MACRO X
MOV AX,X
MOV BX,10
MUL BX
ENDM
;*******定义宏来在指定位置输出msg的内容*****
DISPLAYMSG MACRO MSG,ATTR,ROW,LIE
LOCAL COME,EXITOP ;声明COME,EXIT为本地宏变量
PUSH AX ;别的宏不能调用
PUSH BX
PUSH CX
PUSH DX
PUSH DI
MOV DH, ROW
MOV DL, LIE
MOV BH, 0
MOV BL, ATTR
MOV DI, 0
COME:
MOV AH, 02H ;置光标位置
INT 10H

MOV AL, MSG[DI]
CMP AL, JIESHU
JZ EXITOP ;遇到"$"则转到EXITOP
MOV AH, 09H
MOV CX, 1
INT 10H
INC DI
INC DL
JMP COME
EXITOP:
POP DI
POP DX
POP CX
POP BX
POP AX
ENDM
;******定义宏显示出al中的内容*******
PRINT MACRO COLOR,ROW,LIE
PUSH BX
PUSH CX
MOV AH, 02H ;设置光标的位置
MOV BH,0
MOV DL,LIE
MOV DH,ROW
INT 10H
MOV CX,1
MOV AH,09H ;写字符到光标处
MOV BH,0
MOV BL,COLOR
INT 10H
POP CX
POP BX
ENDM
;******************数据段定义******************
DATA SEGMENT
MYNAME0 DB ' * * ',JIESHU
MYNAME1 DB '******** ************ ******** ******** * * * ******* ',JIESHU
MYNAME2 DB '** * * * * * * * * * * * * * ',JIESHU
MYNAME3 DB '* * * * * * * * * *********** * * ',JIESHU
MYNAME4 DB '* * * * * * * ********** * * ',JIESHU
MYNAME5 DB '* * * * * ********* ******** * * * ',JIESHU
MYNAME6 DB '* * * * * * * ********** * * ',JIESHU
MYNAME7 DB '******** * * * * * * * * * ',JIESHU
MYNAME8 DB ' * * * ******** ********** * ** ',JIESHU
FILENAME DB '1.TXT',0
RIGHTMSG DB 'RATE: 00.00%$'
TIME DB 'THE TOTALTIME: 00:00:00$'
WELCOMEWORD DB '>>>>>>WELCOME TO USE THIS PROGRAM<<<<<<',JIESHU


MADEBY DB '-----DESIGNED BY OUYANGKAI (2003090240320)-----',JIESHU
MSG1 DB '******PRESS "ENTER" TO START!********$'
MSG2 DB '*********PRESS " ESC" TO OUT THE PROGRAM!**********$'
MSG3 DB '>>>>>>>>PRESS ANY KEY TO EXIT TO DOS<<<<<<<<$'
MSG4 DB '>>>>>>>>THANK YOU FOR USEING THIS PROGRAM<<<<<<<<$'
ALLRIGHTMSG DB 'RATE: 1 0 0%$'
HANDLE DW ? ;保存文件名
ARRAY LABEL BYTE;使同一个内存地址可用不同类型的符号表示
;用LABEL定义的符号不占用任何内存空间。
COUNT DW 0
LINELENGTH DW 0
FILELENGTH DW 0
RIGHTWORD DW 0 ;正确字符数
TOTALWORD DW 0 ;用户打字总数
STARTROW DB 5 ;定义作为显示文本里面文字的开始行
CONTRAST DB 71h ;作为中间量和实时钟的秒数对比
SEC DW 0 ;秒
MIN DW 0 ;分
HOUR DW 0 ;时
CORRECT DW 4 DUP(0) ;指定百分比为4位有效数字
BUF DB 128 DUP(?) ;缓冲区,存放读到的文字
BYE0 DB ' __________ _ _ ___________ ',JIESHU
BYE1 DB ' / ______ | \ \ / / / __________| ',JIESHU
BYE2 DB ' | / | | \ \ / / | | ',JIESHU
BYE3 DB ' | | / | \ \ / / | | ',JIESHU
BYE4 DB ' | |_____/ / \ \ / / | |_______ ',JIESHU
BYE5 DB ' | / \ \ / / | _______| ',JIESHU
BYE6 DB ' | _____ \ \ / | | ',JIESHU
BYE7 DB ' | | | \ | | | | ',JIESHU
BYE8 DB ' | | | | | | | | ',JIESHU
BYE9 DB ' | \_____| | | | | |_________ ',JIESHU
BYE10 DB ' \__________| |___| \___________| ',JIESHU
DATA ENDS
;********************堆栈段定义***************************
STACK SEGMENT PARA STACK 'STACK'
DB 256 DUP(?)
STACK ENDS
;****************下面为主程序************
CODE SEGMENT
ASSUME DS:DATA,CS:CODE,SS:STACK
MAIN PROC FAR
START:
PUSH DS
MOV AX,0
PUSH AX
MOV AX,DATA
MOV DS,AX

MOV AH,0
MOV AL,11h ;定义显示方式,全屏
INT 10H

CALL WELCOME
CLS:
CALL JIEMIAN


MOV DX,OFFSET FILENAME
MOV AH,3DH;AL=0为读文件,AH=3DH是功能号
MOV AL,0
INT 21H
MOV HANDLE,AX

AG:
MOV BX,HANDLE
MOV AH,42H ;移动文件指针的中断
MOV AL,0 ;定义为从文件头移动
MOV CX,0 ;CX:DX为位移量
MOV DX,FILELENGTH ;文件长度传给DX
INT 21H

MOV BX,HANDLE
LEA DX,BUF
MOV CX,50 ;读文件里的字节数为50
MOV AH,3FH
INT 21H

MOV BX,AX ;AX=实际读到的字符数
MOV BUF[BX],JIESHU ;在读到文字最后添加"$"符
MOV BX,0
CREND:
CMP BUF[BX],CR ;检测文本里的回车键
JZ CHANGCR
CMP BUF[BX],JIESHU ;检测文本里的"$"
JZ ALL
INC BX
LOOP CREND
JMP ALL
CHANGCR: ;遇到回车时把$传给回车处
MOV BUF[BX],JIESHU
ALL:
MOV LINELENGTH,BX
ADD BX,2
ADD FILELENGTH,BX

DISPLAYMSG BUF,0FH,STARTROW,14 ;在(5,14)输出文本字符
INC STARTROW ;输出后增加两行,下次输出就在第7行输出
INC STARTROW
CALL INPUTCHAR ;调用等待用户输入的子程序
JMP AG

QUIT: ;退出程序
MOV BX,HANDLE
MOV AH,3EH ;关闭文本文件
MOV BL,0AH
MOV DL,18
INT 21H
;**************退出界面******************
CALL CLS_SCREEN ;调用清屏子程序
SHOWBYE: ;在屏幕上显示"BYE"
DISPLAYMSG BYE0,BL,6,DL
DISPLAYMSG BYE1,BL,6+1,DL
DISPLAYMSG BYE2,BL,6+2,DL
DISPLAYMSG BYE3,BL,6+3,DL
DISPLAYMSG BYE4,BL,6+4,DL
DISPLAYMSG BYE5,BL,6+5,DL
DISPLAYMSG BYE6,BL,6+6,DL
DISPLAYMSG BYE7,BL,6+7,DL
DISPLAYMSG BYE8,BL,6+8,DL
DISPLAYMSG BYE9,BL,6+9,DL
DISPLAYMSG BYE10,BL,6+10,DL

DISPLAYMSG MSG4,0BH,3,15
DISPLAYMSG MSG3,0BH,22,18
MOV AH,1 ;判断键盘有无输入
INT 16H
JZ SHOWBYE ;无输入则继续显示退出界面
CALL CLS_SCREEN ;返回DOS前先清屏
MOV AH,4CH ;返回DOS
INT 21H
RET
MAIN ENDP
;*****************键盘输入的子程序********************
INPUTCHAR PROC FAR
BEGIN:
CALL DISPLAYTIME ;调用显示时间子程序
MOV AH,1 ;判断有没键盘输入
INT 16H
JZ BEGIN
TH: MOV AH,0 ;读键盘中断
INT 16H

CMP AL,ESCKG ;检测esc键,相同则退出
JZ QUIT

CMP AL,CR ;检测回车键,相同则换行
JZ NEXTLINE
DELETE:
CMP AL,08H ;检测退格键
JZ DELETE_G
JMP HA
DELETE_G:
DEC TOTALWORD ;总数减一
DEC COUNT
DEC DL
MOVTO DH,DL ;光标前进一列
PRINT ' ', DH,DL ;要删除的地方输出空格" ".
dec DL
MOVTO DH, DL
GUANGBIAO ;输出光标"_"
ADD DL,1
MOVTO DH, DL
MOV AH, 08H ;调用读当前光标位置的字符,属性中断
INT 10H
CMP AH, 0aH ;出口参数中ah=字符属性,如果删除的字符颜色为正确
JNZ DEL ;字符的颜色则正确字符数和总字符数都减一
DEC RIGHTWORD;如果颜色为错误的颜色,则只要总字符数加一
DEL:
MOV AL,' '
PRINT 07,DH,DL
JMP TH

HA: INC TOTALWORD ;当有输入时总数加一
CALL ISRIGHT ;并调用检测输入是否正确子程序
INC COUNT
CALL CORRECTRATE ;调用正确百分率子程序
MOV BX,COUNT
CMP BX,LINELENGTH ;当输入的字符和上面一行
JZ NEXTLINE ;显示的字符数目相等时换行
JMP BEGIN
NEXTLINE:
MOV BX,LINELENGTH
ADD BX,15
DEC STARTROW
PRINT 0h,STARTROW,BL ;输出文本里面的下一行
INC STARTROW ;重新等待用户输入
MOV COUNT,0
RET
INPUTCHAR ENDP
;*************显示时间子程序************
DISPLAYTIME PROC FAR
PUSH AX
PUSH BX
PUSH DX
MOV AH,02H ;读实时钟
INT 1AH
CMP DH,CONTRAST ;让CONTRAST跟读出来的秒数比
JZ TIMEEXIT
MOV CONTRAST,DH ;比完后不相同的就把DH传给中间量CONTRAST

;秒数加1,一直循环
INC SEC ;当遇到60时进位
CMP SEC,60
JNZ CONTINUATE
INC MIN
MOV SEC,0
CMP MIN,60
JNZ CONTINUATE
INC HOUR
MOV MIN,0
CONTINUATE:
CALL TENTOASC ;调用10进制转换为ascll码子程序
DISPLAYMSG TIME,0EH,20,15 ;在(20,15)位置显示时间
TIMEEXIT:
POP DX
POP BX
POP AX
RET
DISPLAYTIME ENDP
;***********判断输入是否正确的子程序******************
ISRIGHT PROC NEAR
MOV BX,COUNT ;对比显示和输出的字符是否一致
CMP AL,BUF[BX]
JNZ WRONG ;不一样转移到标注错误的语句
INC RIGHTWORD
DEC STARTROW
MOV BL,ARRAY
ADD BL,14 ;显示的第一个字符定义在14列
PRINT 0AH,STARTROW,BL ;正确的字符显示为浅绿色
MOV BL,ARRAY
ADD BL,15
MOV AL,'_'
PRINT 07H,STARTROW,BL ;在要输入的字符下面打印光标号"_"
INC STARTROW
RET ;当输入和显示一样时变色后返回调用
WRONG:
DEC STARTROW
MOV BL,ARRAY
ADD BL,14
PRINT 0CH,STARTROW,BL ;错误的字符显示淡红色
MOV BL,ARRAY
ADD BL,15
MOV AL,'_'
PRINT 07H,STARTROW,BL
INC STARTROW
RET ;当字符输入不一样时变完颜色后返回
ISRIGHT ENDP


;****************百分率子程序*****************
;正确率(**.**%)算法:正确字符数*10除以正确字符数,得到的商为2进制数,变为ascll码后作为
;正确率的最高位,然后余数*10后继续除以总数,也把商换成ascll码.循环4次输出4位有效数字
CORRECTRATE PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX

MOV CX,4 ;循环4次,得出4位有效数字
MOV BX,0
CLEAR: MOV CORRECT[BX],0 ;让除出来的数分别存放在缓存区里
ADD BX,2
LOOP CLEAR

MOV AX,RIGHTWORD
CMP AX,TOTALWORD ;如果正确数和总数相等则为100%
JZ ALLRIGHT
MOV SI,0
MOV CX,4
X10 RIGHTWORD ;正确数*10
RATELOOP:
MOV DX,0
DIV TOTALWORD ;AX放商,DX放余数
MOV CORRECT[SI],AX
CMP DX,0
JZ ISZERO ;余数是零则跳出除法
X10 DX ;把余数*10继续进行除法运算,
;最后得出4为有效数字
INC SI
INC SI ;数字是16位.所以SI要递增两次
LOOP RATELOOP
ISZERO:
CALL TOASC ;10进制转换为ascll码
DISPLAYMSG RIGHTMSG,0EH,20,50 ;在(20,50)输出转为asc码后的正确率
POP DX
POP CX
POP BX
POP AX
RET ;分为全对和不全对两种情况,所以要分别返回
ALLRIGHT:
DISPLAYMSG ALLRIGHTMSG,0EH,20,50;输出全对的正确率100%
POP DX
POP CX
POP BX
POP AX
RET
CORRECTRATE ENDP
;********将一位十进制数转换为ASCII码*********
TOASC PROC NEAR ;一位的十进制转为asc码只要加上30H即可
PUSH BX
PUSH CX
MOV CX,4
MOV BX,0
CHANGE:
ADD CORRECT[BX],30H ;让除出来的商都加上30H
ADD BX,2 ;correct定义为字节型,所以一次递增2
LOOP CHANGE

;循环4次,算出4为有效数字

MOV AX,CORRECT
MOV SI,6 ;rightmsg地址下的第6个字符
MOV RIGHTMSG[SI],AL ;把已经加上30H的商的第0偏移地址的数据传给rightmsg字符串第6个字符
;传给rightmsg字符串第6个字符字符串里的字符是从0开始算起的
MOV AX,CORRECT[2]
MOV RIGHTMSG[SI+1],AL
MOV RIGHTMSG[SI+2],'.';把"."传给rightmsg的第8个偏移地址数
MOV AX,CORRECT[4]
MOV RIGHTMSG[SI+3],AL
MOV AX,CORRECT[6]
MOV RIGHTMSG[SI+4],AL
POP BX
POP CX
RET
TOASC ENDP
;******小于100的十进制数转化为ASC码****
TENTOASC PROC NEAR
MOV BL,10 ;要转换的数除以10分离出商和余数,分别放在AL和AH中
MOV AX,SEC ;分别加上30H即转换为ASC码
DIV BL
ADD AL,30H ;商转换为ascll码
MOV SI,22 ;把指针指向time地址里面字符串的最后一个0
MOV TIME[SI-1],AL
ADD AH,30H ;余数也转换为ascll码
MOV TIME[SI],AH ;把秒数放在time的最后两个0的偏移地址下
MOV BL,10 ;定义颜色
MOV AX,MIN ;--------------把分钟数放在第3,4个0处
DIV BL
ADD AL,30H
MOV TIME[SI-4],AL
ADD AH,30H
MOV TIME[SI-3],AH
MOV BL,10
MOV AX,HOUR ;---------------把小时数放在第1,2个0处
DIV BL
ADD AL,30H
MOV TIME[SI-7],AL
ADD AH,30H
MOV TIME[SI-6],AH
RET
TENTOASC ENDP

;**********************输出外围框架子程序******************
KUANG PROC
PUSH AX
PUSH CX
PUSH DX
MOV BL,9AH
MOV AH, 0
MOV AL,3
INT 10H
MOV CX, 79 ;定义循环79次
MOV DH, 0
MOV DL, 0
AGAIN1: ;显示上框
INC DL

MOV AL,'*'
PRINT BL,DH,DL
LOOP AGAIN1

MOV CX, 24
AGAIN2: ;显示右框
INC DH
PRINT BL,DH,DL
LOOP AGAIN2

MOV CX, 79
AGAIN3: ;显示下框
DEC DL
PRINT BL,DH,DL
LOOP AGAIN3

MOV CX, 24
AGAIN4: ;显示左框
DEC DH
PRINT BL,DH,DL
LOOP AGAIN4

MOV CX,79 ;重新定位光标在(18,0)
MOV DH,18
MOV DL,0
MOV AL,'@'
AGAIN5: ;在第18行显示一行"@"
PRINT BL,DH,DL
INC DL
LOOP AGAIN5
POP DX
POP CX
POP AX
RET
KUANG ENDP
;*****************欢迎界面***************
WELCOME PROC FAR
PUSH AX
PUSH DX
PUSH BX
CALL KUANG
SHOW:
DISPLAYMSG WELCOMEWORD ,0EH,3,20
DISPLAYMSG MADEBY ,05H,5,20
DISPLAYMSG MSG2,0AH,20,13
DISPLAYMSG MSG1, 0AH,22,20
MOV BL,0AH
MOV DL,4
DISPLAYMSG MYNAME0,BL,7,DL
DISPLAYMSG MYNAME1,BL,8,DL
DISPLAYMSG MYNAME2,BL,9,DL
DISPLAYMSG MYNAME3,BL,10,DL
DISPLAYMSG MYNAME4,BL,11,DL
DISPLAYMSG MYNAME5,BL,12,DL
DISPLAYMSG MYNAME6,BL,13,DL
DISPLAYMSG MYNAME7,BL,14,DL
DISPLAYMSG MYNAME8,BL,15,DL

MOV AH,0 ;读键盘输入
INT 16H
CMP AL,CR ;检测到回车时跳转到打

字程序
JZ CLS

CMP AL,ESCKG ;检测为esc键时跳到程序退出
JZ QUIT
JMP SHOW
POP BX
POP DX
POP AX
RET
WELCOME ENDP
;**************打字界面子程序***************
JIEMIAN PROC FAR
CALL KUANG
DISPLAYMSG MSG2,0AH,22,13
DISPLAYMSG WELCOMEWORD ,0EH,1,20
DISPLAYMSG MADEBY ,0EH,3,19
RET
JIEMIAN ENDP
;***********清屏子程序***********
CLS_SCREEN PROC FAR

MOV AH,15
INT 10H
MOV AH,0
INT 10H
RET
CLS_SCREEN ENDP

CODE ENDS
END START

相关文档
相关文档 最新文档