汇编语言与微机接口课程设计-多功能电子钟

简介: 汇编语言与微机接口课程设计-多功能电子钟

一、课程设计目的

掌握综合使用基本输入输出设备、通用接口芯片、专用接口芯片的方法;

掌握实时处理程序的编制和调试方法。

二、设计内容及具体要求

设计一个定时显示装置,用实验仪的八个LED数码管显示时间,时间显示格式为24小时制,如14-35-45。具体完成如下几个功能:

1)通过键盘设置时间。

2)整点报时功能。分秒值为59分55秒时开始报时,每秒钟蜂鸣器鸣叫一声,到整点报时停止。

3)设置闹钟功能。闹钟时间到,蜂鸣器开始鸣叫,鸣叫时间最长半分钟。可通过按键停止蜂鸣。

键盘控制时钟的启停和时间的设置,键的定义参见上图。

F键(启停键)—— 程序启动后,按下该键时钟启动;再次按下该键,暂停计时,显示当前时间。

C键(设置键)—— 按下C键后,为时钟设置时、分、秒初始值。

D键(设置键)—— 按下D键后,设置闹钟的时、分初始值。

E键(闹钟控制键)——闹钟响的时候,按下该键,闹钟停止。

三、所需实验器件

使用星研实验箱,8255系列模块、8253模块、8259模块、小键盘、数码管、蜂鸣器。

四、设计的方案及电路原理

设计总体方案

image.png

硬件连线方案


image.png

五、软件的流程图

划分出软件设计模块,给出主程序和子程序的详细的设计流程图,并加以文字说明.

整体流程

主程序的总体流程如图所示。首先,对各个芯片进行初始化。也需要对内存进行初始化。初始化完成后,主程序循环地刷新数码管,并采用查询的方式判断是否有按键输入。若没有按键输入,则继续反复刷新数码管。若有按键输入,则判断该按键是哪个按键,根据按键的值处理该按键,调用后文涉及到的模块的子程序。在循环地刷新数码管与查询输入的过程中,接受时钟中断,进行计时。

数码管

数码管显示的过程如图所示。需要说明的是,数码管显示的流程与课本上讲解的大同小异,但仍然存在一定区别。星研开发环境中,位码端口多接了一个反相器,所以位码也是低有效。

键盘扫描

键盘读入过程如图所示。需要说明的是,由于在设计内存空间时,是直接将键盘量读入并按位置翻译成数码管的段码,所以需要调用一个子程序将数码管的段码翻译回数值。尽管键盘看起来是4行4列的,但是实质上是2行8列的。在细扫描读取的过程中,先控制列线在该位输出0,读该列的行值。若该列没有读取到0,则读取下一列。直到所有列都被读取完毕。

输入时间

此图为C键实现的设置时分秒功能流程:在设置时间的时分秒初始值时,先关中断,不进行计时。没设置的位被显示为横杠。在设置的过程中,可随时按键盘上的A键退出设置,此时,时钟的低位保持不变,时钟的高位为重新设置的值。在流程的每一步之间,都需要穿插适当延时。在“接受输入”的流程之前,都需要设置一定的延时。首先,从高到低,先设置小时。若小时的十位>=3,则输入不合法。需要重新输入。若小时的个位>=10或小时的十位>=2的情况下小时的个位>=4(即小时为24、25等值而不是20、21、22、23)等合法值,则需要重新输入小时的低位。接下来,设置分钟。若分钟的十位>=6,则输入不合法,重新输入。若分钟的个位>=10,则需要重新输入分钟的低位。同样的,需要设置秒钟。若秒钟的十位>=6,则输入不合法,需要重新输入。若秒钟的个位>=10,也需要重新输入秒钟的低位。在设置完时间后,按新设置的时间重新开始计时。

设置闹钟

此图为D键设置闹钟的流程,与C键实现的设置当前时分秒的流程是大同小异的。区别在于:D键不需要开关中断,因为后台仍然在计时。D键也不需要设置闹钟精确到秒。在设置闹钟时,调用到的内存区域也与C键不同,数码管显示的内容也不同。所以,调用的数码管显示的子程序也不同。在数码管显示时,只需显示前5位:小时十位、小时个位、横杠、分钟十位、分钟个位。剩余3位不显示。但是同样的,在流程的每一步,都需要设置延时。

关停闹钟

此图为E键关停闹钟的流程。闹钟是否响的控制由变量stopclock值控制。按E键只会对stopclock取反码。在计时的中断服务子程序中,读取该stopclock值以控制闹钟是否会响。

计时开关

此图为F键开启或关闭计时的流程。闹钟是否响的控制由stop变量控制。先对stop取反。若stop值为0FFH,则关中断,暂停计时。若stop值为0,则开中断,重新启动计时。

六、软硬件调试过程

调试过程:软硬件的调试过程并非是一帆风顺的。本人的在课程设计中的工作多与硬件相关。在调试硬件时,可以先点击“全速运行”检测本次编程是否成功。若测试时发现出现问题,则在相应的模块的子程序设置断点,在断点处添加寄存器观察窗与变量观察窗,对程序进行调试与debug。需要说明的是,硬件运行中出现的问题并非完完全全与程序有关,也有可能与硬件的刷新率有关。有些问题在断点调试的过程中不容易发现,例如数码管的“闪烁”现象与键盘读入过快等问题。这些问题与解决办法在下文中将会展开叙述。

出现问题1

当我们机械地照搬课本上对于数码管显示的汇编代码时,我们并没有在机箱上正确地实现预期的效果(每一位分别显示不同数字)。经过我们单步调试与研究,我们发现:在实验环境所用机箱上,由于内部自带一个反相器,所以数码管的段码与位码都是低电平有效的,与课本存在一定的区别。

解决方法:修改代码,位码全改成低电平有效。

出现问题2

数码管出现“闪烁”的现象。该现象有两种表现:某一位上某时会出现不应当出现的数字并很快熄灭。或每一秒数码管都会短暂熄灭。

解决方法:首先,对于每个子程序,都需要找到其入口参数与出口参数,分析其使用的寄存器,将寄存器入栈保护。因为闪烁现象的原因之一就是软件内存放段码与位码的内存区域被某一子程序越界访问。其次,在数码管每一位显示完毕后都得设置“适当延时”。若延时过短,则某一位点亮后被立即熄灭,在全速运行时体现为亮度不够。若延时过长,则也会导致闪烁的现象,在某一位置闪出了不该出现的数字。在调试过程中,需要经过反复测试,才能确定合适的延时。该延时约为5次空操作所需时间。

每一秒,数码管都会短暂熄灭。这是因为中断服务子程序过于长,系统需要非常长的时间执行该中断服务子程序,而没有时间执行数码管显示。解决办法也很简单:在中断服务子程序中,插入几次对显示数码管的调用。

出现问题3

使用跳转指令时,被提示跳转指令超出范围,编译不通过。

解决方法:尽管理论上段内直接转移的位移量为64KB(-32768~32767),但实际上,星研环境中段内直接转移位移量只能为8位(-128~127)。超过这个范围,就会编译不通过。因此,在汇编程序内需要控制程序先跳转到一个范围在(-128~127)的某个位置,再在那个位置跳转到程序真正需要到达的位置。

出现问题4

扫描键盘时,本应当一次只读入一位数字,但是按下按键时把多位数字全读入成该按键的值。

解决方法:在扫描键盘子程序内设置一定的延时。经测试,该延时约为65536次空操作所需的时间。

七、设计总结

系统已经实现的功能:

1.利用8个LED数码管显示时间,时间的格式为HH-MM-SS。利用C键设置时钟的时、分、秒初始值。利用F键控制时钟的启动与停止。

2.整点报时功能。在每小时的59分55秒开始报时,每秒蜂鸣器响一次,到00分00秒停止。

3.设置闹钟功能。闹钟时间到,蜂鸣器开始响。通过按键停止蜂鸣器。利用D键设置闹钟的时、分初始值。利用E键关停闹钟声音。

值得改进的地方与改进措施:

由于时钟展示程序直接沿用了之前实验课上的8255开关量输入功能,本程序可能会将某个数的段码、行列码、数值反复转化,引入了过多冗余的过程。同时,可能由于某些软件子程序过长,我们在按键盘开关量时轻按可能无效,需要用大力度按压按键。

改进措施:对代码进行整理与重新组织,进一步将各个模块分离。

有哪些创新方法

可以在闹钟与报时时产生音乐,而非只是产生正弦波。

八、课程设计的收获及心得体会

附录:源程序清单(包含关键的注释)

https://download.csdn.net/download/qq_46640863/81571620


目录
相关文章
|
12月前
|
API
4.10 x64dbg 反汇编功能的封装
LyScript 插件提供的反汇编系列函数虽然能够实现基本的反汇编功能,但在实际使用中,可能会遇到一些更为复杂的需求,此时就需要根据自身需要进行二次开发,以实现更加高级的功能。本章将继续深入探索反汇编功能,并将介绍如何实现反汇编代码的检索、获取上下一条代码等功能。这些功能对于分析和调试代码都非常有用,因此是书中重要的内容之一。在本章的学习过程中,读者不仅可以掌握反汇编的基础知识和技巧,还能够了解如何进行插件的开发和调试,这对于提高读者的技能和能力也非常有帮助。
87 0
4.10 x64dbg 反汇编功能的封装
|
2月前
|
存储 Unix 编译器
汇编语言----X86汇编指令
汇编语言----X86汇编指令
43 1
|
2月前
|
存储 机器学习/深度学习 移动开发
汇编语言指令系列
汇编语言指令系列
126 0
|
12天前
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
|
4天前
|
C语言
程序技术好文:部分ARM汇编指令解读
程序技术好文:部分ARM汇编指令解读
|
2月前
|
安全 编译器
8086 汇编笔记(四):[BX] 和 loop 指令
8086 汇编笔记(四):[BX] 和 loop 指令
|
2月前
|
Shell C语言 SoC
计基2—RISCV指令集介绍与汇编
计基2—RISCV指令集介绍与汇编
34 1
|
2月前
|
存储 C++
C/C++中的整数除法运算与汇编指令DIV和IDIV
C/C++中的整数除法运算与汇编指令DIV和IDIV
32 1