3.4出错原因的分析
出错情况:
1. 无法取出数据段的数据。 2. 编译通过,运行无法通过。 3. 单步调试通过,全速运行无法进行。 4. 无法显示频率。 5. 启动开关无法检测。 出错原因分析及解决方法:
1. 我一开始定义一个数据段即data segment….data ends,然后取里面的数据,无论如
何都不行,我看了一下实验箱手册里的例子,他们全没用到data段,而是数据段和代码段共用,用ds :code 及push cs,pop ds来解决。因此我分析的结果是实验箱不支持的问题,我在PC机上用汇编均支持。
2. 经老师指点,是因为代码长了,实验箱的监控程序不支持,通过滑动下载软件上的
延迟到高的部分解决了。
3. 我是用一个循环来检测计时器0的输出情况,由于我在循环里忘了加一条IN指令,
而陷入死循环,加了后解决了。
4. 主要是不了解8279的原理及使用方法,还有数码管的编码方式,通过查看文档资
料及摸索解决了。
5. 这个问题跟第3点类似,也是在循环里忘了先用IN指令读取数据,再用AND截取
数据检测。发现后加了IN指令解决了。
4经验与教训
小组成员:刘晓泽 体会:
这是一个小的项目开发,我试着用规范的方法去做,我在项目开始时先想着确定一个题目,老师推荐了几个题目,又要求一个小组只能有一个且不能重复。因此我们选了频率计作为我们的项目。一开始时我并不知道什么是频率计,然后询问了老师。大概明
11
白了,后来在课上我在百度里打频率计,然后在百度百科里看了一下什么叫频率计以及频率计的主要原理是什么,这个比较重要。我觉得做一个陌生的项目,首先搞明白这个项目的概念及原理,这样才能下手。我看了一下我们那个HK88TE这个实验箱,以及实验箱可用的部分,感觉只能完成方波的测试,因此进行了方波的频率计设计。我进行了需求分析,搞明白了我们到底要干什么,以及是否在规定的时间内可行,以及取得所做项目所需的技术知识及资料,这些统统在第一次课后进行了准备。我把老师给的资料全打印下来了。
由于我们做的是频率计,那么必然有显示的输出部分,以及频率的输入部分,还有处理转换这样3个主要模块。这三个模块中所需的知识只有显示部分之前没遇到过。剩下的在上学期的微机原理用过,而且第一次课的时间又熟悉了一下,还是比较熟悉的,忘了的命令字翻翻书也就能解决了,欠缺的是8279这个芯片的使用方法和原理。第一次课后,我便把8279的资料全看了,由于我只用到显示部分,因此主要看显示部分的原理和操作。
第一次课时我并不清楚6个数码管的显示方法,后来仔细看了实验台上的数码管,通过看例子以及自己的推测,发现一个数码管是用1个字节里的数据来显示的,按照数码管上的标号,从a到h,按照顺时针方式旋转,0表示灭,1表示亮,这样的信息用8位数据里的低字节到高字节表示。
我是这样认为的,实验课的时间是十分宝贵的,主要是用来搞硬件的,即主要是用来验证自己对硬件的理解以及调试自己的电路和代码的,不是主要用来编程和看资料的。而实验箱比较贵,听说几千块,而且实验结束或者十分了解实验箱后,实验箱对自己的作用也不大,实验箱主要是教学用,不必一人买一个。不像学习单片机,买个51芯片,自己焊电路那样,可以长期持有,使用。而且用51单片机芯片自己搞一个电子产品,价格也很低,很实用。因此,我在课下尽量地花时间编程和看资料,在课上尽可能地调试程序,以及检验自己的电路。
我在假期时,有自己买过一些单片机芯片自己玩。但是,我跟别人学单片机不太一样。由于自己是计科的,专业方向不同,很难花大量的时间在电子方面。但由于有些兴趣,也自己在假期有空时学学。发现单片机的核心还是编程,当把电路搭好后,原理也明白后,剩下的大量时间是在编程。因此,总的来说对自己的专业方向偏差不大。
我是在网上听说有人用面包板来学习单片机的。就是买上一块面包板和线,由于面包板上有一个个小孔,用线插拔十分方便,不用焊东西,对自己的学习十分有利。然后
12
我就照着别人的推荐买了51单片机,不过这个是国产的STC系列的芯片,因为它是国产,自然网上的官方文档是中文版的,对于英语不好的我来说比较方便。买了一些晶振什么的就在面包板上接起来,然后照着例子看着原理图学习。用的是C语言编程。
后来在实验课上想用C语言,发现实验平台的软件不支持,而我用的芯片是8088CPU。所以最终就用汇编来编程了,尽管过程中有一段痛苦的过程,但是随着我把自己的实验完成,又自己玩了一下其它人做的什么时钟、计算器、电子琴和交通灯,这样我间接在硬件课程的这段时期编了几千行的汇编代码。尽管我自己的实验是只有200行代码,但是我在这几千行的代码编程中中对汇编比较自信,也不再恐惧它了。
我在使用汇编中没用到多少种指令,也就是常用的那20几种。什么MOV、JMP、LEA、RET、CALL、ADD、SUB、MUL、ADD、DIV、IN、OUT、JL、JZ、JA、JNZ、LOOP、INC、DEC、AND、NOT、SLL、SLR、PUSH、POP。
我也就熟悉这么些指令。
我在网上看到的频率计的原理是:通过在单位时间内检测出的频率数,用
,
其中为测出的方波频率,N为单位时间内的频率数,T为单位时间(项目里为0.5S)。这样求出的即为频率,单位是HZ。
我就用这条几句话的原理进行方波频率计的设计。开始时想自己买芯片来焊(尽管我不是很自信,但是知道一点原理,我觉得可行),但是我们大三上学期的课程太多了,一天8节课,不光有硬件的课程设计,还有软件工程的课程设计,觉得在时间上可能安排不过来。而且这学期的专业课程比较重要,很多都是原理,而且有些课程的老师不错,不花时间的话,可能过了这村就没这店了。我认为本科生与专科生的差别在于理论原理的研究。本科生普遍比职业学校的学生缺少动手时间和经历,而职业学校的学生由于一开始的生源不同,他们在理论学习上的时间要少,学习能力稍差。而缺乏理论原理的学习,在技术上很快会到达瓶颈。而他们再学习能力有限,再自我学习理论原理时就会遇到困难,自学能力也有限。因此,就必须找到一个平衡点。因此,我在不落下平常的课程的学习下,尽可能多地动手做实验,编程。
我把我们的项目分析了一下,发现必须用中断。而实验箱有缺陷,上学期马海波老师教我们微机原理,当时他说我们实验箱缺少中断的连接口,所以我们上学期的实验也就没有中断的实验。中断有两种方法实现,即软中断和硬中断。而硬件中断方式,实验
13
箱无法实现,那么只能采取软件中断。软中断就是用循环来实现,尽管很浪费CPU资源,但是也算是一种响应不错的方法。软中断也是比较不好把握的,因为必须把全局所需要处理的内容的顺序安排好。把需要不断检测及更新的部分全部安排在一起,一次一次地扫描。而其余的安排在这个代码段的外面。
开这门课之前,我在课余时间看了几页反汇编的书,就是看原先C语言编的代码在转成汇编时如何实现的。里面的函数在转成汇编代码时,是在调用前把所谓的参数入栈,然后用CALL命令将程序段调入(在C里叫函数),在程序段的末尾用RET指令返回调用处。我大概看了一些CALL指令,这个指令可以用JMP和PUSH指令代替,其本质是把当前的CPU状态入栈,把IP寄存器内容入栈,然后用JMP跳到相应的标号,即代码段上偏移的地址处执行指令。而RET就是把之前入栈的内容按顺序出栈。由于用这两条指令省事,而且让人更了解代码的内容和思想,我在以后的编码中经常用。
编汇编是十分头疼的事情,至少在开这门课之前。编300行的汇编和编300行的C绝对不是一个数量级的,如果不处理好汇编代码的结构,那么将比较痛苦。
借鉴了这些思想,我采用模块化的思想将这个程序划分成一个个功能独立的代码,用一些PUSH、POP语句充当像C语言中的形参。我尽量将这些功能代码做成像软件工程这门课说的高内聚低藕合的模块。当一个模块有小问题时,影响不大,只修改这个模块即可,而模块又可以迅速地组合,扩展。我用这个方法,在完成自己小组的实验下,自己又做了一些别人的项目内容。而我在这有限的几周内完成了几个项目,当然,交报告肯定只是自己该交的部分,其它的就当自己练练手。学习学到手,毕竟是最重要的,不闭拘于形式。
我平常花比较多的时间在编程,一些开发辅助工具没怎么关注。因此当画我们这个项目的流程图以及原理的逻辑结构图时是用WINDOWS里的画图工具和WORD配合完成的,尽管就三幅图,花了一个下午,可能有4个小时,比较艰难和辛苦。
项目程序分为主程序和功能小程序。通过在主程序中依次调用功能小程序来完成全部功能,旁边也附加大量的注释,方便小组成员的交流,以及代码的修改。
这个程序的主体思想是这样的:
首先用一段循环检测程序段检测是否有开关按键按下,没有就一直循环检测,检测到便对8253赋初始值,让0通道在外界输入1/8MHZ的情况下,通过赋值62500计数,在方式0下产生0.5秒的定时。而计时器0的输出接输入芯片,通过一个循环不断检测计时器0是否定时完毕。而计时器1的CLK1端口接带检测的方波频率,这个计时器是
14
在方式2下工作的,每次频率计工作都赋初始值0给它,让它在单位时间内对产生的脉冲计数。通过里是65535,即
,
,其中N为最终的计数值,
为计数的最大值,这
是计时器1上读出的计数值,N为测出的频率数。然后
将N转换成8279能显示的数码,最后用8279显示出来。接着继续用一段代码检测在这当中用一个开关负责开启检测和重置。有的话,代码又跳转到最开始执行。即第一次使用拨动开关,不到1秒即出来结果,以后每拨动2次,即可看到结果。
在编程的过程中也遇到不少的问题,例如: 出错情况:
6. 无法取出数据段的数据。 7. 编译通过,运行无法通过。 8. 单步调试通过,全速运行无法进行。 9. 无法显示频率。 10. 启动开关无法检测。 出错原因分析及解决方法:
6. 我一开始定义一个数据段即data segment….data ends,然后取里面的数据,无论如
何都不行,我看了一下实验箱手册里的例子,他们全没用到data段,而是数据段和代码段共用,用ds :code 及push cs,pop ds来解决。因此我分析的结果是实验箱不支持的问题,我在PC机上用汇编均支持。
7. 经老师指点,是因为代码长了,实验箱的监控程序不支持,通过滑动下载软件上的
延迟到高的部分解决了。
8. 我是用一个循环来检测计时器0的输出情况,由于我在循环里忘了加一条IN指令,
而陷入死循环,加了后解决了。
9. 主要是不了解8279的原理及使用方法,还有数码管的编码方式,通过查看文档资
料及自己摸索解决了。
10. 这个问题跟第3点类似,也是在循环里忘了先用IN指令读取数据,再用AND截取
数据检测。发现后加了IN指令解决了。
经过这些过程我们小组便在第三周的开始接受老师的检验并通过了。老师拿来一个频率发生器,开到方波进行检验,在我们的频率计可显示的范围内通过了。
后来我们便是作报告,以及自己做自己想做的其它实验。
15