本站首页    管理页面    写新日志    退出


«November 2025»
1
2345678
9101112131415
16171819202122
23242526272829
30


公告

谦卑,荣誉,牺牲,英勇,怜悯,诚实,精神,公正。


我的分类(专题)

日志更新

最新评论

留言板

链接

 

 


Blog信息
blog名称:
日志总数:183
评论数量:698
留言数量:7
访问次数:3044284
建立时间:2005年12月29日




[硬件东东]电子钟-汇编程序
网上资源

newqiang 发表于 2006/1/4 22:37:58

电子钟-汇编程序         主要实现汇编语言下面的电子钟功能.提供主要的设置时间,设置闹铃,显示时间等功能       下面是程序,已经在MASM5下编译运行通过..但有个缺点,也是明显的,就是CPU占用率太多.日后有时间再更正好了. (请尊重原创,如果引用,请注明出处.) ;***************************************************************************;Author: ChengZengcun();Date  : 2005/12/24;Email : bohemia1985@163.com;College: Zhejiang University of Science and Technology;Subject:A simple Colck program writen by Asmble language.;function: Display Time;                Set Time;                Set Clock Ring;                Set Display Style ;***************************************************************************;程序简介:; 采用驻留中断程序的方式,将系统定时器提供给用户的ICH中断进行重新设计,加载新的; 处理程序,使得每秒得到中断。主程序首先注册新的中断处理程序,从系统取得系统时间; 然后无限等待,直到在中断程序中检测到有按键事件的发生,然后,主程序取消中断处理程序,; 开始判断输入的键,然后根据相应的按键,提供相应的设计功能。; 中断处理程序每次得到系统定时器的中断时,判断是否到达1秒(约18.2次为1秒)。如果到达; 则,更新时间,存入数据区,然后更新数据的显示。当有按键事件发生时,设置数据区的按键; 标记为'真'。当主程序检查到该标记为真时,则取消中断程序的驻留。然后处理相应的事件。;;主要步骤:; 1.定义显示界面; 2.调用系统时间,并将得到的二进制数值转换成ASCII码,将数据存入内存; 3.定时的将存在内存区的时间数用显示字符串的形式显示出来(采用ICH中断); 4.获取键盘按键值,判断键值决定是否退出系统或执行其他功能; 5.时间设定功能,通过键盘设定时,分,秒(时:分:秒); 6.闹钟功能,定时报声(时:分); ;存在的缺点:; 1.对输入时间的格式没有严格控制,比如输入11:11:11 同11'11'11,或 11,11,11;   同样的效果;; 2.当程序运行时,由于主程序无限循环,然后等待中断刷新时间,因为无限循环,因此;   占用CPU使用时间比较多。以后扩展可采用一些方式比如,WAIT,HLT等功能实现资源的;   节省。; 3.有些函数可以进一步进行抽象和整合。从而使得代码数量减少。;;参考书籍:IBM-PC汇编语言程序设计(第2版),沈美明,温冬婵,清华大学出版社;    296页,中断向量的设置与恢复;;    301页,定时器中断程序;    389页,通用发声程序;*************************************************************************** .model small;------------------------------------------------------------------------- .stack;------------------------------------------------------------------------- .data HOUR     db  ?MIN         db  ?SEC        db  ?MSEC     db  ?   NHOUR         db 0 ;设置时间使用NMIN              db 0   ;设置时间使用NSEC             db 0 ;设置时间使用 RHOUR         db 1 ;设置闹铃时间使用RMIN               db 1 ;设置闹铃时间使用RSEC             db 1 ;设置闹铃时间使用 FUNKEY db ? ;功能设置使用 keySw    db 00h ;是否按键开关RingSw db 00h ;闹铃开关  SWITCH db 0FFh ;刷新开关,真,则不断在定时器中断函数中刷新,否则不刷新  n db 0dh,0ah,'$' count dw 1   sMsg         db '****  welcome to Simple clock   ****',0dh,0ah,'$' qMsg         db '**** Please Input q to quit  ****',0dh,0ah                    db '  ','**** Input s to set new Time ****',0dh,0ah                    db '  ','**** Input r to set ringTime ****',0dh,0ah,'$' setTMsg   db 'Please Input new Time(HH:MM:SS)',0dh,0ah,'$' setRMsg   db 'Please Input Ring Time(HH:MM)',0dh,0ah,'$'  authorMsg db '---------------------------------------',0dh,0ah            db 'Author:ChengZengcun',0dh,0ah            db 'E-mail:bohemia1985@163.com',0dh,0ah            db 'Zhejiang University of Science and Technology',0dh,0ah            db 'Version 1.0',0dh,0ah            db 'Date:2005/12/23',0dh,0ah            db '---------------------------------------',0dh,0ah,'$' ;------------------------------------------------------------------------- .code  PUSHA     MACRO       PUSH DS              PUSH      AX              PUSH      BX              PUSH      CX              PUSH      DX          ENDM POPA      MACRO              POP DX              POP CX              POP BX              POP AX       POP DS          ENDM ;----------------------------------------------------------------------------;Main program main proc far    start:         mov ax,@data ;allot data segment         mov ds,ax         push ds  ;store the ds ;get the System time         call  GETTIME ;取得系统时间         call initUI  ;初始化界面 ;save old interrupt vector         mov al,1ch  ;al<=vector number         mov ah,35h  ;to get interrupt vector         int 21h  ;call DOS          push es  ;save registers for restore(old base address)         push bx  ;save offset of interrupt 1CH         push ds ;set new interrupt vector         mov dx,offset tUpdate ;dx<=offset of procedure ring         mov ax,seg tUpdate ;ax<=segment of procedure ring         mov ds,ax  ;ds<=ax          mov al,1ch  ;al<=vector#         mov ah,25h  ;to set interrupt vector         int 21h  ;call DOS          pop ds  ;restore ds         in al, 21h  ;set interrupt mask bits         and al, 11111100b         out 21h,al         sti  delay:          PUSHA           cmp ds:[keySw],0FFh ;check if any key is pressed        jz exitdelay ;exit delay if any key is pressed    ringP:   ;闹铃判断          ;mov dl,ds:[MIN]          mov dl,ds:[RHOUR] ;判断闹铃时间(小时)         cmp dl,ds:[HOUR]         jne noRing         mov bl,ds:[RMIN]    ;判断闹铃时间(分钟)         cmp bl,ds:[MIN]         jne noRing          mov dh,ds:[RingSw] ;check if the Ring Switch is On.(只要调用SETRTIME就会打开闹铃开关)         cmp dh,00h         jz noRing          call  GENSOUND ;call GENSOUND to make clock ringnoRing:           POPA         ;wait         jmp delay exitdelay:         POPA         ;restore old interrupt vector         pop dx  ;restore registers(restore the old offset)         pop ds      ;restore old base of interrupt         mov al, 1ch  ;al<=vector#         mov ah, 25h  ;to restore interrupt          int 21h  ;call DOS          pop ds ;restore ds  ;读敲入的按键          mov ah,07h           int 21h         ;mov al,ds:[FUNKEY]         cmp al,'s'         jne next1  ;判断读入字符然后进行相应处理,此时中断函数已经取消,只是单线程 setT:         ; mov ah,07h  ;读字符        ; int 21h         mov ds:[FUNKEY],al           call SETTIME ;调用子函数设置时间        ; mov ah,01h        ; int 21h         mov ds:[keySw],00h         jmp startnext1:         cmp al,'r'         jnz next2         mov ds:[FUNKEY],al          call SETRING;调用字函数设置闹铃时间         mov ds:[keySw],00h          jmp start next2: cmp al,'q'         je endmain         mov ds:[keySw],00h         jmp start endmain:          mov ax,4c00h ;exit         int 21hmain endp ;------------------------------------------------------------------------;定时中断程序();;Introduction:;在系统定时器(中断类型为8)的中断处理程序中,有一条中断指令INT 1CH,;时钟中断每发生一次(约每秒发生18.2次,即55ms发生一次)都要嵌套调用;一次中断类型1CH的处理程序。在ROM BIOS例程中,1CH的处理程序只有一条IRET,;实际上它并没有作任何工作,只是为用户提供了一个中断类型号。如果用户有某种;定时周期性的工作需要完成,就可以利用系统定时器的中断间隔,用自己设计的;处理程序来代替原有的1CH的中断程序。; 本程序就是将原有1CH中断程序进行替换,实现了定时更新时间。采用DOS;中断驻留中断程序。; tUpdate proc near         push ds  ;save the working registers         push ax         push bx         push cx         push dx          mov ax, @data ;allot data segment         mov ds, ax          sti         ;judge if it is time for cUpdate         dec count  ;count for timer interval(约18.2次为1秒)         jnz exit  ;exit if not for 1 second         mov count,18 ;control ring interval delay(10s)         ;call the CALTIME         call  CALTIME  ;更新时间 ;检测刷新开关是否打开         mov bl,ds:[SWITCH]         cmp bl,00         jz exit ;检测是否有按键按下,取适当的值进行退出控制 PUSHA         MOV      AH, 0BH         ;检测是否输入消息(按键消息)         INT      21H         INC  AL         JNZ      nokey          mov  ds:[keySw],0FFh ;设置已经被按键         POPA         jmp exitnokey:         POPA          call DISPLYH  ;显示小时         call DISPLYM  ;显示分钟         call DISPLYS  ;显示秒 exit:          cli         mov al,20h  ;set EOI         out 20h,al          pop dx   ;restore the reg.         pop cx         pop bx         pop ax         pop ds         iret   ;interrupt returntUpdate endp ;--------------------------------------------------------------------;关闭定时刷新开关closeSw proc near         PUSHA         mov bl,0h         mov ds:[SWITCH],bl ;关闭刷新开关         POPA         retcloseSw endp;----------------------------------------------------------;打开定时刷新开关openSw proc near         PUSHA         mov bl,0FFh         mov ds:[SWITCH],bl ;打开刷新开关         POPA         retopenSw endp;---------------------------------------------------------------------------;初始化显示界面,可以在此处添加额外的设置选项initUI proc near         PUSHA  ;设置显示方式(40×25 黑白文本,16级灰度)         mov ah,0h         mov al,00h         int 10h  ;显示头标题         mov dh,00h         mov dl,02h         call MOVCUR         mov dx,offset sMsg ;dx<=offset of sMsg         mov ah,09h  ;to display sMsg         int 21h   ;call DOS  ;显示结尾标题         mov dh,05h         mov dl,02h        call MOVCUR         mov dx,offset qMsg ;dx<=offset of qMsg         mov ah,09h  ;to display qMsg         int 21h   ;call DOS   ;显示作者信息         mov dh,09h         mov dl,00h         call MOVCUR         mov dx,offset authorMsg ;dx<=offset of authorMsg         mov ah,09h  ;to display authorMsg         int 21h   ;call DOS           POPA         retinitUI endp;--------------------------------------------------------------------------;移动光标(dh:row,dl:col); dh ;参数设置行; dl ;参数设置列MOVCUR proc near         PUSHA         ;设置光标位置         mov ah,2h         mov bh,0         int 10h         POPA         ret MOVCUR endp;-------------------------------------------------------------------------;显示小时DISPLYH     PROC     NEAR                        PUSHA         ; 设置光标位置         mov dh,2h ;set Row  No.         mov dl,10d ;set Column NO.         call MOVCUR         mov dh,0         mov dl,ds:[HOUR]         call output ;调用output函数输出小时         mov dl,':'         mov ah,02h         int 21h           POPA         RETDISPLYH ENDP ;----------------------------------------------------------;显示分钟 DISPLYM PROC NEAR                     PUSHA         ;设置光标位置         mov dh,2h ;set Row  No.         mov dl,13d ;set Column NO.         call MOVCUR         mov dh,0         mov dl,ds:[MIN]         call output         mov dl,':'         mov ah,02h         int 21h          POPA         RETDISPLYM ENDP ;----------------------------------------------------------;显示秒DISPLYS PROC NEAR                     PUSHA         ;设置光标位置         mov dh,2h ;set Row  No.         mov dl,16d ;set Column NO.         call MOVCUR         mov dh,0         mov dl,ds:[SEC]         call output        POPA         retDISPLYS endp;----------------------------------------------------------;调用DOS中断取得系统时间GETTIME PROC NEAR                    PUSHA         mov ah,2ch  ;get the System time,CH:CL=(H:M),DH:DL=(s:1/100s)         int 21h         mov ds:[HOUR],CH ;取得小时         mov ds:[MIN],CL ;取得分钟        ; dec DH  ;延迟1秒         mov ds:[SEC],DH ;取得秒         mov ds:[MSEC],DL          POPA         retGETTIME endp ;----------------------------------------------------------;调整时间,累加秒,分,时 CALTIME proc near                    PUSHA   ;调整秒         inc ds:[SEC]         cmp ds:[SEC],60d         jb endc         mov ds:[SEC],0h    setM:   ;调整分钟         inc ds:[MIN]         cmp  ds:[MIN],60d         jb endc         mov ds:[MIN],0h    setH:   ;调整小时         inc  ds:[HOUR]         cmp ds:[HOUR],24d         jb endc         mov ds:[HOUR],0h   endc:         POPA        retCALTIME endp;---------------------------------------------------------------------------;设置时间SETTIME proc near         PUSHA         call closeSw ;关闭定时刷新         mov dh,11h         mov dl,00h         call MOVCUR ;移动光标           mov dx,00h         mov ah,09h  ;输出提示信息,提示输出设置时间         mov dx,offset setTMsg         int 21h          call READNT ;读取时间(HH:MM:SS)  ;设置时间         mov ch,ds:[NHOUR] ;HOUR          mov cl,ds:[NMIN] ;MIN         mov dh,ds:[NSEC] ;SECOND         mov dl,0h   ;1/100 SECOND         mov ah,2Dh         int 21h          cmp al,00h         je SetSuccess           mov ah,02h  ;设置时间中断调用失败处理         mov dl,'!'         int 21h  SetSuccess:         call openSw ;打开刷新开关           POPA         retSETTIME endp;---------------------------------------------------------------------;设置闹铃时间:SETRING proc  near         PUSHA         call closeSw ;关闭定时刷新         mov dh,11h         mov dl,00h         call MOVCUR ;移动光标           mov dx,00h         mov ah,09h  ;输出提示信息,提示输出设置时间         mov dx,offset setRMsg         int 21h          call READRINGT ;读取闹铃时间(HH:MM)          mov ds:[RingSw],0FFH ;设置闹铃开关为 '开' rSetSuccess:         call openSw ;打开刷新开关          POPA         retSETRING endp;------------------------------------------------------------------;读取时间(从ASCII码到16进制数值的转换)(HH:MM:SS)READNT proc near         PUSHA         mov ah,01h           int 21h         mov bx,0h        ;bx存放得到的数值(16进制) loop1: cmp al,'0'  ;读取小时        jl endloop1        cmp al,'9'                         jg endloop1        sub al,30h        ;transform from char to number         cbw         xchg ax,bx        mov cx,0ah        ;put 10d into cx        mul cx              xchg   ax,bx        add bx,ax        mov ah,01h        ;put the read interrupt type                           int 21h           ;call the DOS interrupt                   jmp loop1       ;存取小时endloop1:           mov ds:[NHOUR],bl;          mov bx,0h;               loop2:                mov ah,01h           int 21h     ;bx存放得到的数值(16进制)        cmp al,'0'   ;读取分钟        jl endloop2        cmp al,'9'                         jg endloop2        sub al,30h        ;transform from char to number         cbw         xchg ax,bx        mov cx,0ah        ;put 10d into cx        mul cx              xchg    ax,bx        add bx,ax                jmp loop2            ;存取分钟endloop2:         mov ds:[NMIN],bl         mov bx,0h   loop3:          mov ah,01h           int 21h    ;bx存放得到的数值(16进制)          cmp al,'0'   ;读取秒        jl rlast        cmp al,'9'                         jg rlast                  sub al,30h        ;transform from char to number         cbw         xchg ax,bx        mov cx,0ah        ;put 10d into cx        mul cx              xchg   ax,bx        add bx,ax                 jmp loop3 rlast:                  ;存取秒        mov ds:[NSEC],bl                      POPA         retREADNT endp;----------------------------------------------------------------------------;读取闹铃时间READRINGT proc  near         PUSHA         mov ah,01h           int 21h         mov bx,0h        ;bx存放得到的数值(16进制) rloop1:          cmp al,'0'   ;读取小时        jl rendloop1        cmp al,'9'                         jg rendloop1        sub al,30h        ;transform from char to number         cbw         xchg ax,bx        mov cx,0ah        ;put 10d into cx        mul cx              xchg   ax,bx        add bx,ax        mov ah,01h        ;put the read interrupt type                           int 21h           ;call the DOS interrupt                   jmp rloop1        ;存取小时rendloop1:          mov ds:[RHOUR],bl;         mov bx,0h;               rloop2:                 mov ah,01h           int 21h    ;bx存放得到的数值(16进制)          cmp al,'0'    ;读取分钟        jl rendloop2        cmp al,'9'                         jg rendloop2        sub al,30h        ;transform from char to number         cbw         xchg ax,bx        mov cx,0ah        ;put 10d into cx        mul cx              xchg    ax,bx        add bx,ax                jmp rloop2            ;存取分钟rendloop2:         mov ds:[RMIN],bl          POPA         retREADRINGT endp;-----------------------------------------------------------------------------;闹铃发声程序;;DI,保存发声频率,CX,BX指定发声程序的持续时间GENSOUND proc near         PUSHA         push  DI  ;set the frequency         mov di,020h         mov bx,0FFh          mov al,0b6h  ;write timer mode reg.         out 43h,al         mov dx,12h  ;timer divisor         mov ax,348ch ;1193100HZ/freq         div di         out 42h,al  ;write timer2 count low byte         mov al,ah          out 42h,al  ;write timer2 count high byte         in al,61h  ;get current port setting         mov ah,al  ;and save it in ah         or al,03h  ;turn speaker on         out 61h,al   waitsound:         mov cx,500h  ;wait for specified intevral          delaySound:         loop delaySound         dec  bx         jnz waitsound         mov al,ah  ;recover value of port         out 61h,al         pop DI           POPA         retGENSOUND endp;---------------------------------------------------------------------------;输出字符(dx中存放十进制数值)output   proc    near PUSHA        mov     ax,dx         ;put the final num into ax        mov     dx,00h                     mov     cx,0h trans:                        mov     bx,000ah      ;this loop put the char into memory        div      bx           ;divide 10d        add     dl,30h        ;transform to character      mov dh,0h         push    dx        inc      cx        mov     dx,00h          cmp     ax,00h        jg      trans            cmp cx,01h         jg print  addZero:       ;增加前导0,,比如:02        mov dh,0           mov dl,'0'         push  dx         inc  cx  print:                       ;this loop output the char        cmp     cx,0h          jle     endout        pop     dx mov dh,0        dec     cx         mov     ah,02h        int     21h           ;call DOS output ability                  jmp     print endout:              POPA        retoutput  endp     ;---------------------------------------------------------- end start  ;end assemble  .end Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=561145


阅读全文(15313) | 回复(9) | 编辑 | 精华
 


回复:电子钟-汇编程序
网上资源

上善若水(游客)发表评论于2008/7/2 11:04:11

我的电子钟实现动态模拟显示圆周时刻,并且可以改变指针的颜色,刚缺乏定时功能,谢谢参考。  


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:电子钟-汇编程序
网上资源

小的学习(游客)发表评论于2007/6/22 16:31:01

谢谢了,楼主好厉害.

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:电子钟-汇编程序
网上资源

star(游客)发表评论于2007/1/11 18:59:11

非常感谢,呵呵

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:电子钟-汇编程序
网上资源

sad(游客)发表评论于2007/1/8 18:49:00

hao  

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:求助!各位高手!
网上资源

spring(游客)发表评论于2006/7/7 21:31:04

我是一名学生还是单片机的初学者,现在遇到了些问题请高手指教!!!急!!! 我们有个实验内容是要求用汇编编写一个电子钟的程序,要求:(1)分屏显示"年 月 日"和"时 分 秒"(2)具有整点报时功能(3)时间可以设置 要求用MCS51仿真器,谢谢指教 如果可以请写上设计方案和电路原理图,十分感谢!我的EMAIL:springminmin@hotmail.com 十分感谢高手的指教!

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:电子钟-汇编程序
网上资源

kankan(游客)发表评论于2006/6/5 16:17:55

给个流程图,  

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:电子钟-汇编程序
网上资源

newqiang发表评论于2006/1/9 11:37:24

这个程序我是从网上转的,用来学习。你们可以 Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=561145 请教原作者。谢谢

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:电子钟-汇编程序
网上资源

tornado(游客)发表评论于2006/1/7 17:22:44

有没有流程图

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:求助:有没有用汇编语言编写的21点游戏啊?
网上资源

翠花(游客)发表评论于2006/1/6 13:32:22

有没有用汇编语言编写的21点游戏啊?急用啊!!

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


» 1 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.062 second(s), page refreshed 144805950 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号