最新汇编语言与接口设计课设--电子闹钟(完整版)

电子闹钟

1.摘要

本次课程设计以电子闹钟为主题,旨在利用唐都教学实验平台,通过运用定时计数器8254、并行输入输出接口8255和中断控制器8259,设计出一个功能全面且实用的电子闹钟系统。该系统不仅能够通过七段数码管实时显示当前时间,还具备丰富的功能,包括开始时间的设置、闹钟时间的定时、闹钟的删除和暂停、秒表计时以及整点报时等多种实用功能。

在时间显示方面,系统使用高亮度的七段数码管,确保在各种光照条件下都能清晰可见。定时计数器8254负责生成精确的时钟信号,确保时间的准确流逝,从而使得电子闹钟在运行过程中能够保持高精度。用户可以通过并行输入输出接口8255与系统进行交互,方便地输入和修改闹钟时间,用户还可以利用该接口控制秒表的启动、暂停和重置等功能。

在闹钟设置方面,用户可以简单地通过按键输入设定闹钟时间,一旦设定完成,系统将自动进入定时模式。当系统时间到达设定的闹钟时间时,电子闹钟会通过中断控制器8259触发相应的中断,进而激活蜂鸣器播放预设的音乐,提醒用户起床或进行其他活动。整点报时功能则通过定时器定期检查当前时间,确保在每个整点时刻都能发出提示音,帮助用户掌握时间。

此外,系统还具备秒表计时功能,用户可以随时启动或暂停秒表,便于进行多种计时需求。在实际操作中,用户可以通过简便的操作流程,轻松实现各种功能,提升了使用体验。

整个电子闹钟系统的设计,不仅提高了学生对电子技术的理解和应用能力,还增强了他们的实际动手能力。通过这一项目,学生们能够深入掌握数字电路与微处理器的基础知识,培养解决实际工程问题的能力,为今后的学习和研究打下坚实的基础。这一设计不仅具有教育意义,也为将来的电子产品开发提供了宝贵的实践经验。

关键词:电子闹钟、汇编语言、硬件

使用硬件:芯片8255、8254、8259、蜂鸣器、4*4键盘,集成在唐都实验箱中

2.前言

2.1项目背景

        在当今信息化社会,时间管理对于个人和集体显得尤为重要。无论是在日常生活、工作学习还是各类活动安排中,精确的时间掌控都是提高效率、确保计划顺利执行的关键因素。电子闹钟作为一种基础的时间管理工具,因其便捷、准确和多功能性,已经成为人们生活中不可或缺的设备。为了更好地理解和应用这一重要工具,本次课程设计我们小组以电子闹钟为主题,利用唐都实验箱以及教学实验平台,结合定时计数器8254、并行输入输出接口8255和中断控制器8259,设计出一个功能全面且实用的电子闹钟系统。该系统不仅能够通过七段数码管实时显示当前时间,还具备多种实用功能。首先,用户可以方便地进行开始时间的设置,设定闹钟时间的定时,确保在需要时能够及时提醒。其次,系统还支持秒表计时功能,用户可以随时启动、暂停或重置秒表,以满足不同场合的计时需求。此外,闹钟的删除和暂停功能使得用户能够灵活调整闹钟设置,避免不必要的干扰。在技术实现方面,定时计数器8254负责生成精确的时钟信号,确保时间的准确流逝。并行输入输出接口8255则用于与外部设备进行数据交互,用户可以通过简单的按键输入设置闹钟时间和控制秒表功能。中断控制器8259则用于管理系统中的中断请求,确保在闹钟触发时能够及时响应。当系统时间到达设定的闹钟时间或整点时,电子闹钟会通过蜂鸣器播放音乐,提醒用户注意时间,起到有效的闹钟作用。通过这一项目的设计,学生不仅能够深入理解汇编语言与接口技术的基本原理,还能培养实际动手能力,提升解决实际工程问题的能力。这一电子闹钟系统的开发,不仅为学生提供了实践经验,也为他们未来在电子产品设计和开发领域的学习奠定了坚实的基础。总之,电子闹钟作为一种重要的时间管理工具,其设计与实现不仅具有教育意义,更为日常生活提供了便利,彰显了科技在提升生活质量方面的重要作用。

2.2目的意义 

        本课程设计是《汇编语言与接口技术》课程学习的一个重要组成部分。通过设计和实现电子闹钟项目,学生不仅能够将课堂上学到的汇编语言理论知识应用到实际项目中,还能有效提升自己的编程技能和动手实践能力。汇编语言作为一种底层编程语言,其学习和应用对深入理解计算机的工作原理和硬件控制方法至关重要。通过对汇编语言的掌握,学生能够更好地理解计算机内部的操作流程,从而在编程时做出更为精准和高效的决策。在电子闹钟项目的实施过程中,学生需要利用定时计数器8254、并行输入输出接口8255和中断控制器8259等硬件组件,这些都是汇编语言应用的重要场景。通过实际编写代码,学生不仅能够巩固所学知识,还能在调试和优化程序的过程中,锻炼解决问题的能力。这一过程不仅是对技术能力的挑战,也是对逻辑思维和创造力的考验。此外,项目的设计、编程和调试工作通常需要团队合作,这为学生提供了一个良好的合作平台。在这个过程中,学生们必须有效沟通,分工合作,分享各自的见解和解决方案。这种协作不仅提升了团队成员间的沟通能力,也增强了他们的团队协作意识,使他们在未来的学习和工作中能够更好地适应团队环境。总之,通过电子闹钟项目的设计与实现,学生能够在实践中深化对汇编语言及接口技术的理解,提升编程能力和实践技能。同时,团队合作的经历也为学生的综合素质提升提供了重要的支持。这一课程设计不仅是技术知识的应用,更是对学生综合能力的全面培养,为他们今后的学习和职业发展奠定了坚实的基础。 

 

3.主要任务 

3.1项目概述

        该项目将完成电子时钟设计、闹钟响铃设计、整点报时设计、暂停时间设计、删除闹钟设计、秒表计时设计和设置当前时间的功能,从而实现电子闹钟的设计。电子时钟首先能计时,即每过1秒秒数加1,接着能够显示六位数字,其中从左到右依次为时、分、秒。每过1秒,显示屏更新一次。当小时二十三进二十四时,时、分、秒归零。闹钟响铃功能要求将用户设置好的时间储存起来,在电子闹钟运行时将当前时间与设置好的时间进行比较,当时间一样时,扬声器工作。整点报时功能要求在整点,即秒和分都为0时响一次铃声。设置时间要求能够在任意时刻在小键盘上设置时间,并在数码管上显示出来。设置完成后,电子闹钟能够从设置后的时间开始运行。暂停时间要求能够在任何时刻暂停电子时钟的计时功能,再次操作可恢复计时。删除闹钟要求能够删除之前设置的闹钟。秒表计时要求能够可以开始、停止秒表计时功能。 

 3.2需求分析

功能需求:

  1. 时间显示:实时显示当前时间(时、分、秒),在七段数码管上显示。使用8255实现显示控制,连接LCD或LED显示模块。
  2. 闹铃功能:设置闹铃时间,支持闹铃的开启和关闭。使用8254定时器产生闹铃信号,控制闹铃音频输出。
  3. 时间设置:用户可以手动设置当前时间和日期。通过8255实现按键输入,使用简单的用户界面进行设置。
  4. 整点报时功能:使用8254定时器实现整点报时功能,在整点发出蜂鸣声。
  5. 用户交互:通过8255的输入端口接收用户按键输入,设置时间和闹铃。提供清晰的显示界面,易于用户操作。

性能需求:

1准确性:时钟应准确显示当前时间,误差不应超过一分钟、闹钟应在设定的时间准时触发。

响应速度:操作界面应迅速响应用户的操作、数据更新应即时反映在显示屏上。

2.可靠性:电子闹钟应是稳定的,在运行过程中不应崩溃或出现错误。闹钟触发时应产生清晰的声音和适度的震动,以确保用户被唤醒。

3.3流程分析 

        电子闹钟启动后,首先对系统进行初始化:初始化时间23时 59分59秒,8259A、8255、8254硬件初始化。初始完后,显示当前时间。判断是否按下设置时间或闹铃按键,若按下则进入对应的子程序设置时间或闹铃。否则接着判断当前时间是否为闹铃时刻,是则播放音乐,不是则继续判断是否为整点时刻,若为整点时刻则响铃。最后回到显示时间模块,进行循环。初始化完后的过程是一个循环过程,因此能完成一个时间的更新显示,而计时实现秒数加一是由内部硬件8259A、8254完成。电子闹钟程序流程图如下图所示。 

 

 

4.总体设计 

4.1功能设计

电子闹钟的功能模块图如下图所示: 

 

 4.1.1电子闹钟显示

电子时钟显示主要完成计时,显示时间的功能。

首先计时部分,主要由8259A、计数器8254完成。利用计数器8254分频功能,将系统时钟源CLK为1MHZ分为50HZ,把计数器0的输出端 OUT0接入主片8259A 的中断引脚IR7上,实现每20ms 计数器 0 给 80x86 系统一个中断。对中断进行计数,当中断次数达到50次时,秒数加 1,中断次数清零。

时间子程序用于累加时间。首先,检查秒钟是否大于59(CMP SEC, 3BH)。如果秒钟大于59,表示超过了规定的秒数,将秒钟清零(MOV SEC, 00H),分钟加1。然后,检查分钟是否大于59(CMP MIN, 3BH)。如果分钟大于59,表示超过了规定的分钟数,将分钟清零(MOV MIN, 00H),小时加1。再后,检查小时是否大于23(CMP HOUR, 17H)。如果小时大于23,表示超过了规定的时间(24小时制),那么将小时清零(MOV HOUR, 00H),即重置为零点。

中断执行过程和调用时间累加子程序的过程如下图所示:

 

        显示时间部分主要由并行接口8255、七段数码管组成。系统利用8255 并行接口输出功能向6个七段数码管输出数字,在数码管上显示时间,从左到右分别是时、分、秒。首先判断时间是否合法,接着将时、分、秒分离高位和低位,存储到6个连续的字节变量。然后用并行接口8255的A口输出数码管的选中信号,用B口输出数字对应的字形码。由于每次只能选中一个数码管输出字形码,因此循环执行6次就能完成完整 6个时间数字的显示。每次输出完一个数字就进行延时,利用人的视觉暂留现象,让人感觉数码管是同时亮起。显示时间过程如下图所示: 

 4.1.2闹钟响铃

        闹钟响铃功能主要能够从矩阵键盘上设置闹铃时间,电子时钟运行至闹铃时刻能够响铃,其中上下波动一次K7开关则进行设置闹铃时间,前四位分别为小时的高位低位、分钟的高位低位,第五位为闹钟歌曲曲目,若设置时间不合法则重新设置,直至设置合法。设置闹钟的过程如下图所示。

        响铃部分由定时器8254、扬声器完成。首先判断当前时间是否为闹钟时刻,若为闹钟时刻则播放设置好的相应曲目。一个音符对应一个频率,将对应一个音符频率的方波通到扬声器上,便能发出这个音符的声音。计算设置闹铃曲目的音乐频率表和时间表的偏移地址,控制8254,设置计数初值,在扬声器上演奏相应的乐曲。在响铃时候可以按键结束闹钟。响铃过程如下图所示。 

 

4.1.3整点报时 

        整点报时实现了时钟在运行到整点时刻扬声器能响3秒以达到提示作用。首先判断分钟和秒钟是否为0,是则让8254计数器1输出特定频率的方波让扬声器响起,初始化8254计数器1工作于方式3,给计数器1赋初值,当秒钟达到3时,扬声器停止,返回主程序。整点报时过程大致同上响铃过程。 

4.1.4设置时间 

        设置时间实现了在时钟运行的任何时刻能设置当前时刻。设置时间的信号主要由中断实现,按下按键开关KK1,进入中断子程序设置时间。设置时间需要从键盘上输入6个数,表示时分秒,确定键盘上按下键的位置并转化成数字。屏幕会显示设置的时分秒。矩阵键盘输完6个键后,中断子程序结束,返回主程序。设置时间的流程如下图所示。 

4.1.5暂停时间

         暂停时间实现了在闹钟运行时,拨动开关K6时,进入中断子程序暂停时间,程序停止计时,并持续显示当前时间,直到再次拨回K6,中断子程序结束,返回主程序,暂停时间的流程如下图所示。

4.1.6删除闹钟 

        删除闹钟的操作通过监测连接至8255并行接口芯片C端口的K5开关来实现。当拨动K5开关时,系统通过读取8255的C端口状态来检测这一动作。一旦检测到K5被激活,程序进入一个等待循环,这个循环将持续运行直到释放开关K5,以此来确认删除意图。在等待循环期间,程序执行清除闹钟设置的操作,将存储闹钟时间的变量(Chour、Cmin、Csec)重置为0,这表示闹钟时间已被清除,系统不再保留之前的闹钟设定。当用户释放K5开关后,系统检测到开关状态的变化,随即退出等待循环,完成闹钟的删除过程。此后,程序继续执行或返回主程序,闹钟功能将不再运行,直到重新设置闹钟时间。 

4.1.7秒表计时

        秒表计时功能实现了在闹钟运行时,拨动开关K4时,进入中断子程序开始秒表计时,同时,时钟运行功能正常实现,数码管的六位依次显示当前秒表计时的时、分、秒的高位和低位,在秒表计时过程中,当拨动开关K6时,进入中断子程序暂停秒表计时,秒表停止计时,并持续显示当前秒表计时时间,直到再次拨回K6,中断子程序结束。当再次拨动开关K4时,返回主程序,结束秒表计时,数码管显示时钟运行的时、分、秒。秒表计时的流程如下图所示。 

4.2界面设计 

显示与控制界面如图 7 所示,其中6个七段数码管从左到右分别表示时间的时、分、秒,小键盘从上向下,从左到右,第一排按键分别表示数字 0、1、2、3;第二排按键分别表示 4、5、6、7;第三排按键分别表示 8、9、A、B;第四排按键表示数字 C、D、E、F。

KK1是设置初始时间的按键。默认的初始化时间为23:59:59,触按KK1后过小键盘进行数字输入,6个七段数码管从左到右分别表示时间的时、分、秒,输入6个数,输入完毕即设置成功。

K7是设置闹钟的时、分,以及选择曲目按键。上下拨动K7一次,进入闹钟设置,6个七段数码管从左到右前四个分别表示时、分,第五个和第六个数码管表示闹钟的响铃曲目。

K6是暂停时间,向上拨动一次K6,暂停计时,拨回K6,继续计时。

K5是删除闹钟,上下拨动K5一次,删除已经设置的闹钟。

K4是秒表计时,向上拨动一次K4,开始秒表计时,拨回K4,结束秒表计时。

 

4.3硬件设计 

         该项目主要用到唐都试验箱的中断 8259A、并行接口 8255、定时器 8254、矩阵键盘数码管显示单元、蜂鸣器。

4.3.1 中断控制器8259A

        在 Intel386EX 芯片中集成有中断控制单元(ICU),该单元包含有两个级联中断控制器,一个为主控制器,一个为从控制器。从片的INT连接到主片的TR2信号上构成两片8259的级联。在 TD-PITE 实验系统中,主控制器的 IR6、IR7 以及从控制器的IR1 开放出来供实验使用,主片8259的IR4供系统串口使用。对应本项目完成的电子闹钟的实现,主要用到了 IR7 中断进行计时及 IR6 中断进行设置闹钟。对于芯片初始化命令字说明如下:(第一个为主片第二个为从片)

寄存器

端口地址

控制字

ICW1

20H

11H

ICW2

21H

08H

ICW3

21H

04H

ICW4

21H

01H

寄存器

端口地址

控制字

ICW1

0A0H

11H

ICW2

0A1H

30H

ICW3

0A1H

02H

ICW4

0A1H

01H

 

4.3.2可编程并行接口8255 

        并行接口是以数据的字节为单位与I/O设备或控制对象之间传递信息。8255可编程外围接口芯片是Intel公司生产的通用并行I/O接口芯片,它具有A,B,C三个并行接口,用+5V单电源供电,有三种工作方式。该项目使用 8255 主要向数码管单元输出用于显示数字及接收矩阵键盘的信号、开关K7等的信号。对于 8255 控制说明如下: 

         

8255 的 A 口工作于方式 0,输出到数码管用于显示数字。PA0 至 PA5 工作于模式 0 输出至矩阵键盘单元的列选线 X1~X6,C 口 PC0~PC3 连接键盘单元行线 Y1~ Y4,接收键盘的信号,PC7 接收开关 K7 信号,8255 的方式控制字为 89H。

4.3.3定时、计数器8254

 8254是Intel公司生产的可编程间隔定时器。定时器 8254 计数器 0 用于产生中断信号,计数器 1 输出特定频率方波至蜂鸣器播放音乐。8254 的控制方式与控制字格式如下表所示:

让计数器每 20ms 产生一次中断,中断达到 50次时,秒数加 1,中断次数清零,从而达到电子时钟定时秒针加 1 的功能。计数器0连接到中断控制器8259A,采用先读/写低八位再读/写高八位,采用方式3进行分频与二进制数,控制字为36H。

5.详细设计

 5.1整体思路

        8255A芯片是一个可编程的并行接口芯片,可以实现多个输入输出通道的控制。电子闹钟启动后,首先对系统进行初始化:初始化时间 23时 59分59秒,8259A、8255、8254 硬件初始化。初始完后,显示当前时间。通过 8255 接口输出至数码管,一次选中一个数码管并输出段码显示,循环 6 次显示完整时间。运行过程中判断是否按下设置时间或闹铃按键,若按下则进入对应的子程序设置时间或闹铃。设置时间时,从矩阵键盘输入 6个数字设置时间。运行时判断当前时间是否为闹铃时刻,是则播放音乐,不是继续判断是否为整点时刻,若为整点时刻则响铃。播放音乐通过 8254 输出特定频率并延时至蜂鸣器。最后又回到显示时间模块,进行循环,期间可通过拨动K6开关将时间暂停、拨动K7开关设置闹钟、拨动K5开关删除已设置闹钟、拨动K4开关进入秒表计时。 

5.2实验线路设计 

 

5.3软件设计 

函数名

功能

INIT8259A

初始化8259A

INIT8254

初始化8254

INIT8255

初始化8255

DISPLAY1

显示时钟

ISCLOCK

判断是否是闹钟时间

ISTIME

判断是否是整点

MIR7

处理8254定时器的中断,更新时钟时间。

MIR6

中断子程序,设置当前时间

C8255SETCLOCK

设置闹钟时间

ADCLOCK

实现秒数加一

SETNUM

从小键盘读取输入,并显示在屏幕上

DALLY

延时显示

BELL

播放闹钟

MAIN

程序的主循环,调用显示时间、设置时钟、检测闹钟和整点报时等功能。

DISPLAY2

显示秒表计时的时间。

C8255DELTIME

清除闹钟设置。

C8255STOPTIME

暂停时钟计时。

C8255SCONSECOND

开始、暂停和继续秒表计时,存储和显示秒表时间。

 

5.4实际线路接线 

 

6.遇到的问题和解决办法 

因为更换了新版的实验箱,和我们原本设计的线路有所不同,在新的实验箱里没有SIR1,我们在查阅了新实验箱的使用手册后对原本设计的线路进行了修改,不再使用SIR1,将8255可编程并行接口的C口高四位作为功能键使用,即PC4~PC7四个接口接入到开关单元K4~K7上,在程序中,采用不断检测这四个开关的开闭状态来选择是否执行功能程序。

在刚开始测试时,打开开关,蜂鸣器会一直响无法停止,由于我们的代码设置的初始时间是23:59:59秒,因此程序开始运行之后会立刻进入到00:00:00时刻,这是就会跳入整点报时的程序中并且发出蜂鸣,而整点报时的程序在SETOUT退出时,由于代码的设置错误,程序仍然向计数器1输出方波,这就会导致OUT1向蜂鸣器一直发出信号,导致一直响个不停。在经过测试和修改SETOUT之后,成功解决了这个问题。

在进行秒表计时功能设计时,我们开始设计的是:进入子程序后,把当前的时间直接设置为00:00:00,这样就相当于一个简单的秒表,但是却会导致当前时间的丢失,因此我们增加了一系列新的变量,用来保存秒表的时间,并且让这个变量随着原有时钟同时运行。秒表计时少不了暂停的功能,但是这里不能直接使用已经实现的暂停时间功能,因为这个功能实现的方法是CLI禁止中断,这样时钟信号就不会继续运行,也就不会增加时间,等时间继续的时候再开启中断,恢复运行。不能使用的原因有二:其一,如果禁止中断,那么原来的时间就会跟着暂停。其二:进入秒表的时候会时钟处于秒表程序内部的循环中,而我们实现的暂停时间子功能并不是以中断的方式实现的,而是在主程序中不断检测开关的状态来判断是否进入了暂停时间子功能中,因此在循环中拨下开关并不能使用暂停时间的功能。最终的解决方法是,把秒的时间保存下来,并在循环中不断把该时间传送给秒表时间,然后显示。

7.总结 

 通过这次课程设计,我们深入探讨了电子闹钟的设计与实现,能够清晰理解如何进行时间的设置、闹钟时间的定时以及整点报时等功能的开发。小组成员在讨论课中积极交流,掌握了汇编语言指令的用法,熟悉了汇编语言程序设计的基本方法和结构。这一过程中,我们对Intel 8259A、8255和8254等接口芯片的功能和控制方法有了更深入的认识,结合具体项目的设计与实现,使我们对80X86汇编语言的相关知识以及上述接口电路的工作原理有了更为全面的理解。

在项目的实施过程中,我们面临了许多挑战,比如如何优化代码以提高运行效率,如何处理各种边界情况等。这些问题的解决不仅考验了我们的技术能力,也锻炼了我们的逻辑思维和创造力。        通过不断的尝试和调试,我们逐渐掌握了项目的核心功能,并成功实现了电子闹钟的各项功能。

此外,项目的实施不仅是技术知识的应用,更是团队合作能力的锻炼。在小组合作中,每位成员都承担了不同的任务,大家互相配合,确保项目的顺利推进。通过这种合作,我们不仅提高了各自的责任感和任务完成能力,还培养了总结、归纳、整理和交流的技巧。在讨论和协作中,我们学会了倾听他人意见,尊重不同的观点,这种团队协作能力的提升对于我们未来的学习和工作都具有重要的意义。

在此,我们特别感谢我们的老师,感谢您在整个课程设计过程中给予我们的指导和支持。您的耐心教导和专业知识为我们的学习提供了极大的帮助,使我们能够在实践中更好地理解和应用汇编语言及接口技术。您激励我们探索和创新,让我们在项目中充分发挥各自的特长,提升了我们的综合能力。

最后,此次课程设计不仅提高了我们综合应用已有知识解决实际问题的能力,更加深了我们对计算机专业知识的理解和应用。通过实际操作,我们培养了扎实的专业技术能力和良好的综合素质,为未来的学习和职业发展奠定了坚实的基础。这一项目的完成,不仅是对我们所学知识的检验,更是对我们团队合作精神和解决复杂问题能力的全面提升。再次感谢老师的辛勤付出,您对我们的教导将伴随我们继续前行。

8.参考文献资料 

[1]叶继华等.汇编语言与接口技术[M].北京:机械工业出版社,2005.

[2]沈美明等.IBM - PC汇编语言程序设计[M].北京:清华大学出版社,1999.

[3]索梅等.80386/80286汇编语言程序设计[M].北京:清华大学出版社,1995.

 

9.代码实现 (完整代码)

A8254 EQU 06C0H
B8254 EQU 06C2H
C8254 EQU 06C4H
CON8254 EQU 06C6H
A8255 EQU 0600H
B8255 EQU 0602H
C8255 EQU 0604H
CON8255 EQU 0606H
DATA SEGMENT
	count DB 00H
	hour DB 17H
	min  DB  3BH
	sec  DB 3BH
	Chour DB 01H
	Cmin DB 01H
	SELSONG DB 01H
	Csec  DB 00H
	Shour DB 00H
	Smin DB 00H
	Ssec DB 00H
    tsec DB 00H
	tmin DB 00H
	thour DB 00H
    
	buffer db 6 DUP(?)
	DTABLE DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
	DPTABLE DB 0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH
	KNFR_LIST  DW  495,467,416,624      ;柯南    频率表
           DW  495,416,467,661,624,556
           DW  495,556,495,556,624,495,467,467,556,495,467
           DW  495,416,624,495,556,833,742,661,624,556,624
           DW 580,624,990,833,772,833,990,935,833,742,742
			DW 833,495,556,556,495,556,624,495,556,624,661
			DW 624,556,833,742,661,742,833,935,0
	KNTI_LIST  DB  2,2,4,8     ;柯南    时间表
     	   DB  2,2,4,4,2,4
     	   DB  2,2,2,2,4,2,2,4,4,2,6
     	   DB  4,4,4,4,4,4,4,4,2,2,12
     	   DB  2,2,4,4,4,2,2,2,4,4,8
			DB 4,2,2,2,2,2,12,2,2,2,4
			DB 2,10,4,2,2,2,4,20
     TWTIG_LIST DW 330,371,416,330  ;两只老虎  频率表 
     			DW 330,371,416,330
     			DW 416,441,495
     			DW 416,441,495
     			DW 495,556,495,441,416,330
     			DW 495,556,495,441,416,330
     			DW 330,248,330
     			DW 330,248,330,0
     TWTIG_TIME DB 4,4,4,4          ;两只老虎   时间表 
     			DB 4,4,4,4
     			DB 4,4,8
     			DB 4,4,8
     			DB 2,2,2,2,4,4
     			DB 2,2,2,2,4,4
     			DB 4,4,8
     			DB 4,4,8
	DJTCFR_LIST DW  371,495,495,495,624,556,495,556,624      ;友谊地久天长    频率表
           DW  495,495,624,742,833,833,833,742,624
     	   DW  624,495,556,495,556,624,495,416,416,371
     	   DW  495,833,742,624,624,495,556,495,556,833
     	   DW  742,624,624,742,833,990,742,624,624,495
           DW  556,495,556,624,495,416,416,371,495,0
	DJTCTI_TIME DB    4,  6,  2,  4,  4,  6,  2,  4,  4      ;友谊地久天长    时间表
     	   DB    6,  2,  4,  4, 12,  1,  3,  6,  2
     	   DB    4,  4,  6,  2,  4,  4,  6,  2,  4,  4
     	   DB   12,  4,  6,  2,  4,  4,  6,  2,  4,  4
           DB    6,  2,  4,  4, 12,  4,  6,  2,  4,  4
     	   DB    6,  2,  4,  4,  6,  2,  4,  4,  12
	YJMFR_LIST DW  782,935,1040,1248,1112,1040,935,782,935,782  ;一剪梅   频率表 
			DW 520,624,700,782,700,624,700,624,580,520
			DW 520,782,700,624,580,624,580,520,467,520,0

	YJMTI_TIME DB  1,1,12,1,1,1,1,1,1,12                        ;一剪梅   时间表 
		DB 1,1,12,1,1,1,1,1,1,12
		DB 2,6,1,1,2,2,2,1,1,12

	FREQ_LIST1 DW 494,587,523,494,440,587
         DW 523,494,440,440
         DW 392,349,349,392,330
         DW 0FFFFH,330
         DW 330,330,330,659,587,659
         DW 0FFFFH,0FFFFH,523
        DW 494,494,494,523,523
         DW 0FFFFH,523
         DW 587,523,494,440,587
         DW 523,494,440,440
         DW 392,349,349,392,330
         DW 0FFFFH,330
         DW 330,330,330,659,587,659
         DW 0FFFFH,0FFFFH,523
         DW 494,494,494,523,523
         DW 0FFFFH,0FFFFH
        DW 0
     TIME_LIST1 DB 3, 6, 3, 3, 6, 6
           DB 6, 6, 6, 3
           DB 9, 3, 6, 3, 12
		   DB 12, 3
		   DB 6, 3, 6, 3, 3, 3
		   DB 12, 9, 3
		   DB 6, 3, 6, 3, 15
		   DB 12, 3
		   DB 6, 6, 3, 6, 6
		   DB 6, 6, 6, 3
		   DB 9, 3, 6, 3, 12
		   DB 36, 9
		   DB 18, 9, 18, 9, 9, 9
		   DB 12, 9, 3
		   DB 6, 3, 6, 3, 15
		   DB 12, 3
    FRFR_LIST DW KNFR_LIST,TWTIG_LIST,DJTCFR_LIST,YJMFR_LIST
	TITI_LIST DW KNTI_LIST,TWTIG_TIME,DJTCTI_TIME,YJMTI_TIME
	SFREQ DW ?
	STIME DW ?
     
DATA ENDS
SSTACK SEGMENT
   DW 32 DUP(?)
SSTACK ENDS
CODE SEGMENT
	ASSUME CS:CODE,DS:DATA,SS:SSTACK
START:
	MOV AX,DATA
	MOV DS,AX
	PUSH DS
	CALL INIT8259A
	POP DS
	CALL INIT8254
	CALL INIT8255
MAIN:

	CALL DISPLAY1
	CALL C8255SETCLOCK
	CALL C8255STOPTIME
	CALL C8255DELTIME 
	CALL C8255SCONSECOND
	CALL ISCLOCK
	CALL ISTIME
	JMP MAIN


INIT8259A PROC    ;初始化8259A
	MOV AX,0000H
	MOV DS,AX
	MOV AX,OFFSET MIR7
	MOV SI,003CH
	MOV [SI],AX
	MOV AX,SEG MIR7
	MOV [SI+2],AX
	;填入MIR6中断程序入口地址
	MOV SI,0038H
	MOV AX,OFFSET MIR6
	;MOV AX,OFFSET SIR1
	MOV [SI],AX
	MOV AX,SEG MIR6
	;MOV AX,SEG SIR1
	MOV [SI+2],AX


	CLI
	MOV AL,11H  ;ICW1
	OUT 20H,AL
	MOV AL,08H  ;ICW2
	OUT 21H,AL
	MOV AL,04H  ;ICW3
	OUT 21H,AL
	MOV AL,01H  ;ICW4
	OUT 21H,AL
	;初始从片8259
	MOV AL, 11H
    OUT 0A0H, AL            ;ICW1
    MOV AL, 30H
    OUT 0A1H, AL            ;ICW2
    MOV AL, 02H                
    OUT 0A1H, AL            ;ICW3
    MOV AL, 03H
    OUT 0A1H, AL            ;ICW4
    MOV AL, 0FDH
    OUT 0A1H,AL                ;OCW1
    MOV AL,28H
    OUT 21H,AL        ;主8259 OCW1
    MOV AL,0E6H      
    OUT 20H,AL       ;主8259 OCW2
	STI
	RET
INIT8259A ENDP

INIT8254 PROC    ;初始化8254
	MOV DX,CON8254
	MOV AL,36H
	OUT DX,AL
	MOV AX,4E20H
	MOV DX,A8254
	OUT DX,AL
	MOV AL,AH
	OUT DX,AL
	RET
INIT8254 ENDP 

INIT8255 PROC
	MOV DX,CON8255
	MOV AL,89H
	OUT DX,AL
	RET 
INIT8255 ENDP
;8254每20ms给IR7一个中断 

MIR7:
	STI
	INC count
	CMP count,3CH           ;中断次数达50次 
	JNZ EXIT
	CALL ADCLOCK
	CALL ADCLOCK2
	MOV count,00H
EXIT:
	MOV AL,20H
	OUT 20H,AL
	IRET
	
;mir6中断设置当前时间
MIR6:
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	CALL SETNUM   ;从键盘获取数字存放输入缓冲区 
	LEA DI,hour
	MOV SI,3005H
	MOV CX,03H
;键盘输入的6个数转化为时分秒,高位乘10加低位 
LOOPMIR6:
	MOV AL,[SI]
	MOV BL,0AH
	MUL BL
	MOV AH,[SI-1]
	ADD AL,AH
	MOV [DI],AL
	SUB SI,02H
	INC DI
	LOOP LOOPMIR6
	MOV AL,20H
	OUT 20H,AL
	POP DX
	POP CX
	POP BX
	POP AX
	IRET	
;8255检测闹钟并设置闹钟,设置闹钟时间及闹铃曲目	
C8255SETCLOCK PROC
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	MOV DX,C8255
	IN AL,DX
	TEST AL,80H
	JZ SETOUT
RESETCLK1:
	CALL SETNUM
	LEA DI,Chour
	MOV SI,3005H
	MOV CX,03H
LOOPSIR11:
	MOV AL,[SI]
	MOV BL,0AH
	MUL BL
	MOV AH,[SI-1]
	ADD AL,AH
	MOV [DI],AL
	SUB SI,02H
	INC DI
	LOOP LOOPSIR11
	;判断输入闹钟是否合法,否则重新设置,时小于24,分小于60,选择曲目高位小于4 
	CMP Chour,17H 
	JNG CPCMIN1
	MOV SI,3005H
	JMP RESETCLK1
CPCMIN1:
	CMP Cmin,3BH
	JNG SECSONG
	MOV SI,3005H
	JMP RESETCLK1
SECSONG:
	CMP SELSONG,27H
	JNG SETOUT
	MOV SI,3005H
	JMP RESETCLK1
SETOUT:
	POP DX
	POP CX
	POP BX
	POP AX
	RET
C8255SETCLOCK ENDP

;8255检测删除键,删除闹钟
C8255DELTIME PROC
    PUSH AX
    PUSH BX
    PUSH CX
    PUSH DX
    MOV DX,C8255
    IN AL,DX
    TEST AL,20H
    JZ SETOUT1
    
LOP1:
    CALL DISPLAY1
    MOV Chour,00H
    MOV Cmin,00H
	MOV DX,C8255
    IN AL,DX
	TEST AL,20H
	JNZ LOP1

SETOUT1:
    POP DX
    POP CX
    POP BX
    POP AX
    RET
C8255DELTIME ENDP

;8255检测暂停键,停止计时
C8255STOPTIME PROC
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	MOV DX,C8255
	IN AL,DX
	TEST AL,40H
	JZ SEETOUT
	CLI
LOP:
	CALL DISPLAY1
	IN AL,DX
	TEST AL,40H
	JNZ LOP
	STI
SEETOUT:
	POP DX
	POP CX
	POP BX
	POP AX
	RET
C8255STOPTIME ENDP

;8255检测到秒表键,开始秒表计时
C8255SCONSECOND PROC
   PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	MOV DX,C8255
	IN AL,DX
	TEST AL,10H
	JZ SEEETOUT
	MOV SSEC,00H
    MOV SMIN ,00H
    MOV SHOUR ,00H

    ;不执行CALL DISPALY2,不显示时间
   
   LOOP3:
    CALL DISPLAY2

    IN AL,DX 
    TEST AL,40H
    JZ K
    mov cl,ssec
    mov tsec,cl
    mov cl,smin
    mov tmin,cl
    mov cl,shour
    mov thour,cl
STOP:
    mov cl,tsec
    mov ssec,cl
    mov cl,tmin
    mov smin,cl
    mov cl,thour
    mov shour,cl
    CALL DISPLAY2
    IN AL,DX
    TEST AL,40H
    JNZ STOP
K:
	IN AL,DX
	TEST AL,10H
	JNZ LOOP3
SEEETOUT:
	POP DX
	POP CX
	POP BX
	POP AX
	RET
C8255SCONSECOND ENDP


ADCLOCK2 PROC

	CMP ssec,3BH
	JZ A11
	INC ssec
	JMP OVER1
A11:
	MOV ssec,00H
	CMP smin,3BH
	JZ A21
	INC smin
	JMP OVER1
A21:
   MOV smin,00H
   ;INC shour
   CMP shour,17H
   JZ A31
   INC shour
   JMP OVER
A31:
	MOV shour,00H
	JMP OVER1
OVER1:
	RET
ADCLOCK2 ENDP


   
;调整时间 中断满50次实现秒增一	
ADCLOCK PROC
	CMP sec,3BH
	JZ A1
	INC sec
	JMP OVER
A1:
	MOV sec,00H
	CMP min,3BH
	JZ A2
	INC min
	JMP OVER
A2:
   MOV min,00H
   ;INC hour
   CMP hour,17H
   JZ A3
   INC hour
   JMP OVER
A3:
	MOV hour,00H
	JMP OVER
OVER:
	RET
ADCLOCK ENDP






;显示当前时间	
DISPLAY2 PROC
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	;判断输入数字是否合法 Shour小于24 Smin Ssec小于60
	CMP shour,17H
	JNG CPMIN
	MOV shour,00H
CPMIN:
	CMP MIN,3BH
	JNG CPSEC
	MOV smin,00H
CPSEC:
	CMP ssec,3BH
	JNG CPOVER
	MOV ssec,00H
CPOVER:
	LEA SI,buffer
	LEA DI,shour
	MOV CX,02H
;时分秒转换为6个数字存放输出缓冲区buffer 
LOOP11:
	LEA BX,DTABLE
	MOV AL,[DI]
	CBW
	XOR AH,AH
	MOV DL,0AH
	DIV DL     ;获取Shour Smin高位
	XLAT       ;获取高位字形码 
	MOV [SI],AL
	INC SI
	LEA BX,DPTABLE
	MOV AL,AH    ;获取hour min低位
	XLAT         ;获取低位字形码 
	MOV [SI],AL
	INC SI
	INC DI
	LOOP LOOP11
	LEA BX,DTABLE
	MOV AL,[DI]
	CBW
	XOR AH,AH
	DIV DL
	XLAT
	MOV [SI],AL
	INC SI
	MOV AL,AH
	XLAT
	MOV [SI],AL
;显示时钟,一次选中一个数码管,输出8位字形码 
	MOV CX,06H
	MOV SI,OFFSET buffer
	MOV BL,0FEH   ;1111 1110 选中第一个数码管 
LOOP21:
	MOV AL,BL
	MOV DX,A8255
	OUT DX,AL
	MOV DX,B8255
	MOV AL,[SI]
	OUT DX,AL
	CALL DELAY
	ROL BL,1     ;选中下一个数码管 
	INC SI
	LOOP LOOP21
	

	
	POP DX
	POP CX
	POP BX
	POP AX
	RET 
DISPLAY2 ENDP


;显示当前时间	
DISPLAY1 PROC
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	;判断输入数字是否合法 hour小于24 min sec小于60
	CMP hour,17H
	JNG CPMIN1
	MOV hour,00H
CPMIN1:
	CMP MIN,3BH
	JNG CPSEC1
	MOV min,00H
CPSEC1:
	CMP sec,3BH
	JNG CPOVER1
	MOV sec,00H
CPOVER1:
	LEA SI,buffer
	LEA DI,hour
	MOV CX,02H
;时分秒转换为6个数字存放输出缓冲区buffer 
LOOP1:
	LEA BX,DTABLE
	MOV AL,[DI]
	CBW
	XOR AH,AH
	MOV DL,0AH
	DIV DL     ;获取hour min高位
	XLAT       ;获取高位字形码 
	MOV [SI],AL
	INC SI
	LEA BX,DPTABLE
	MOV AL,AH    ;获取hour min低位
	XLAT         ;获取低位字形码 
	MOV [SI],AL
	INC SI
	INC DI
	LOOP LOOP1
	LEA BX,DTABLE
	MOV AL,[DI]
	CBW
	XOR AH,AH
	DIV DL
	XLAT
	MOV [SI],AL
	INC SI
	MOV AL,AH
	XLAT
	MOV [SI],AL
;显示时钟,一次选中一个数码管,输出8位字形码 
	MOV CX,06H
	MOV SI,OFFSET buffer
	MOV BL,0FEH   ;1111 1110 选中第一个数码管 
LOOP22:
	MOV AL,BL
	MOV DX,A8255
	OUT DX,AL
	MOV DX,B8255
	MOV AL,[SI]
	OUT DX,AL
	CALL DELAY
	ROL BL,1     ;选中下一个数码管 
	INC SI
	LOOP LOOP22
	
	
	

	
	POP DX
	POP CX
	POP BX
	POP AX
	RET 
DISPLAY1 ENDP

DELAY PROC
   PUSH CX
	MOV CX,02F0H
DELAY1:
	PUSH AX
	POP AX
	LOOP DELAY1
	POP CX
	RET
DELAY ENDP
;判断响铃时刻 
ISCLOCK PROC
		MOV AL,hour
		CMP AL,Chour
		JNZ ISOVER
		MOV AL,min
		CMP AL,Cmin
		JNZ ISOVER
		MOV AL,sec
		CMP AL,Csec
		JNZ ISOVER
		CALL BELL
ISOVER:
		RET 
ISCLOCK ENDP
;判断整点时刻 
ISTIME PROC
		CMP sec,00H
		JZ ISMIN
		JMP JUDGEOVER
ISMIN:
		CMP min,00H
		JZ ALARM
		JMP JUDGEOVER
ALARM:
		MOV DX,CON8254
		MOV AL,76H
		OUT DX,AL
ALRLOOP:
		CALL DISPLAY1
		MOV DX,B8254
		MOV AL,00H
		OUT DX,AL
		MOV AL,09H
		OUT DX,AL
		MOV AL,sec
		CMP AL,03H
		JE JUDGEOVER
		JMP ALRLOOP
JUDGEOVER:
		MOV DX,B8254
		MOV AL,0FFH
		OUT DX,AL
		MOV AL,0FFH
		OUT DX,AL
		RET
ISTIME ENDP 

;从键盘获取数字存放输入缓冲区 		
SETNUM PROC    
		MOV AX,DATA
		MOV DS,AX
 		MOV SI,3000H
		MOV AL,00H
		MOV [SI],AL				;清显示缓冲
		MOV [SI+1],AL
		MOV [SI+2],AL
		MOV [SI+3],AL
		MOV [SI+4],AL
		MOV [SI+5],AL
		MOV DI,3005H
        MOV DX,CON8255		;写8255控制字
        MOV AL,89H
		OUT DX,AL
BEGIN:  CALL DIS				;调用显示子程序
		CALL CLEAR				;清屏
		CALL CCSCAN				;扫描
		JNZ INK1
		JMP BEGIN
INK1:   CALL DIS
        CALL DALLY
        CALL DALLY
        CALL CLEAR
		CALL CCSCAN
		JNZ INK2				;有键按下,转到INK2
		JMP BEGIN

;确定按下键的位置
INK2:   MOV CH,0FEH
		MOV CL,00H

COLUM:  MOV AL,CH
        MOV DX,A8255
		OUT DX,AL
        MOV DX,C8255 
		IN AL,DX

L1:     TEST AL,01H         ;is L1?
        JNZ L2

        MOV AL,07H          ;L1
		JMP KCODE

L2:     TEST AL,02H         ;is L2?
        JNZ L3

        MOV AL,04H          ;L2
        JMP KCODE

L3:     TEST AL,04H         ;is L3?
        JNZ L4

        MOV AL,01H          ;L3
		JMP KCODE

L4:     TEST AL,08H         ;is L4?
        JNZ NEXT

        MOV AL,00H          ;L4
		MOV CL,0
KCODE:  ADD AL,CL
		MOV [DI],AL
		DEC DI
		CMP DI,2FFFH
		JNZ KON1
		CALL DIS
		PUSH CX
		MOV CX,0040H
LOOPDALLY:
		CALL DALLY
		LOOP LOOPDALLY
		POP CX
		RET
KON1:	PUSH AX
KON:    CALL DIS
		CALL CLEAR
		CALL CCSCAN
		JNZ KON
		POP AX

NEXT:   INC CL
		MOV AL,CH
		TEST AL,08H
		JZ KERR
		ROL AL,1
		MOV CH,AL
		JMP COLUM
KERR:   JMP BEGIN
		RET
SETNUM ENDP

CCSCAN: MOV AL,00H
        MOV DX,A8255  
		OUT DX,AL
        MOV DX,C8255
        IN  AL,DX
		NOT AL
        AND AL,0FH
		RET

;清屏子程序
CLEAR:  MOV DX,B8255
        MOV AL,00H
        OUT DX,AL
		RET

;显示子程序
DIS:    PUSH AX
		MOV SI,3000H
		MOV DL,0DFH
		MOV AL,DL
AGAIN:  PUSH DX
        MOV DX,A8255 
        OUT DX,AL
        MOV AL,[SI]
        MOV BX,OFFSET DTABLE
		AND AX,00FFH
		ADD BX,AX
		MOV AL,[BX]
        MOV DX,B8255
		OUT DX,AL
		CALL DALLY
		INC SI
        POP DX
        MOV AL,DL
		TEST AL,01H
        JZ  OUT1
		ROR AL,1
		MOV DL,AL
		JMP AGAIN
OUT1:   POP AX
		RET
;延时子程序		
DALLY:  PUSH CX
        MOV CX,0006H
T1:     MOV AX,009FH
T2:     DEC AX
		JNZ T2
		LOOP T1
		POP CX
		RET
;闹钟音乐
BELL PROC
		PUSH AX
		PUSH BX
		PUSH CX
		PUSH DX
		MOV DX,A8255
		MOV AL,7FH
		OUT DX,AL
		MOV DX,CON8254          ;初始化8254工作方式
		MOV AL,76H                  ;定时器1、方式3
		OUT DX,AL
		;取设置曲目,分离高位 
		MOV AL,SELSONG
		MOV AH,00H
		MOV BL,0AH
		DIV BL                   ;计算闹钟音乐的偏移量 
		SAL AL,1
		XOR AH,AH
		LEA SI,FRFR_LIST
		ADD SI,AX
		;MOV SI,BX
		MOV BX,WORD PTR[SI]      ;取出音乐频率表  
		MOV SFREQ,BX       
		LEA SI,TITI_LIST
		ADD SI,AX
		;MOV SI,BX
		MOV BX,WORD PTR[SI]      ;取出音乐时间表 
		MOV STIME,BX	
		;MOV CL,02H
		
		MOV CL,01H
BELLBEGIN:	
		MOV SI,SFREQ    ;装入频率表起始地址
		MOV DI,STIME    ;装入时间表起始地址


BELLPLAY:	MOV DX,0FH                  ;输入时钟为1MHz,1M = 0F4240H  
		MOV AX,4240H                
		DIV WORD PTR [SI]           ;取出频率值计算计数初值,0F4240H / 输出频率  
		MOV DX,B8254
		OUT DX,AL                   ;装入计数初值
		MOV AL,AH
		OUT DX,AL

		MOV DL,[DI]                 ;取出演奏相对时间,调用延时子程序 
		CALL BELLDALLY

		ADD SI,2
		INC DI
		CMP WORD PTR [SI],0000H         ;判断是否到曲末?
		JZ BEGIN1
		JMP BELLPLAY
BEGIN1:
		DEC CL
		CMP CL,0
		JZ OUTPLAY
		JMP BELLBEGIN

OUTPLAY:
		MOV DX,CON8254
		MOV AL,76H
		OUT DX,AL
		POP DX
		POP CX
		POP BX
		POP AX
		RET
BELL ENDP

BELLDALLY	PROC                        ;延时子程序
		PUSH CX
D0:		MOV CX,0010H
D1:		MOV AX,0FF0H
D2:		DEC AX

		JNZ D2
		LOOP D1
		DEC DL
		JNZ D0
		POP CX
		RET
BELLDALLY	ENDP




CODE ENDS
	END START

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值