接口8253虚拟实验的研究_第1页
接口8253虚拟实验的研究_第2页
接口8253虚拟实验的研究_第3页
接口8253虚拟实验的研究_第4页
接口8253虚拟实验的研究_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、摘要2abstract31 问题定义42可行性研究52.1 技术可行性52.2 时间可行性53 需求分析63.1功能需求63.2 性能需求63.3接口要求73.3扩展74 总体设计84.1方案选取84.2模块设计84.2设计数据库94.3测试计划115详细设计125.1程序流程图125.2数据结构设计135.2.1针脚标识135.2.2针脚数据结构135.2.3计数器数据结构145.2.4led灯图片数据结构145.3过程设计145.3.1试图模块155.3.2初始化模块225.3.3示波器模块225.3.4数据库模块236系统测试256.1测试用例256.2测试结果257结论35参考文献37

2、致谢38摘要我们在科研和教学中经常会遇到这样的情况:(一)所用的仪器或者材料过于贵重;(二)仪器或者材料不充足;(三)需要做多次的实验最终才能熟悉过程和操作。在这些情况下我们经常使用计算机软件模拟的方法,即虚拟实验。我此次所研究的题目是“接口8253虚拟实验的研究”。 mfc在windows程序设计中具有相当的优势,因此,采用mfc实现设计,而数据库方面则采用sql server 2000。实现的功能如下:用户可以对8253的三个计数器进行组合和选择并且进行初始化;然后根据选择进行相关仪器的连线;完成后,可以进行运行,而系统则会根据用户的选择情况对连线进行判断,主要涉及方面包括:连线组合是否正

3、确,是否有漏掉的线,电源是否打开,如果连线错误,则会发出报警声,报警灯泡也会亮起,弹出窗口提示用户哪些线路连接出错,并且在实验板上用不同颜色的成对出现的圆圈标出错误地方;如果连线正确则灯泡根据输出值进行闪动,并且此时,用户也可以打开示波器观察波形,在观察的过程中可以更改波形的振幅,可以暂停波形进行观察;而在操作的过程中,用户也可以把自己的实验信息(连线,计数器组合和选择,初始化)进行保存,需要恢复时,只要打开相应文件即可。由于此程序在运行过程中需要和用户进行交互,所以需要用多线程的技术来进行处理。在本程序中,用了两个辅助线程。一个用来处理灯泡的亮和灭,一个用来进行示波器的显示。关键词:虚拟实验

4、,接口8253,mfc,多线程,sql server 2000abstractour research and teaching in such a situation often encountered: (a) equipment or material used is too expensive; (b) equipment or material is not sufficient; (c) the need to do many experiments to be familiar with the process and the operation. in these cases,

5、 we often use the computer software simulation method, a virtual experiment. the subject i studied is interface 8253 study of virtual experiment. mfc programming in the windows has a considerable advantage, therefore, achieve design using mfc, while the database is using sql server 2000. the progami

6、ng achieves the following functions: the users can initialize the counters based on the selections of the them,then bind the circuit lines according to the initialization of the those;when completed,it can be run, and the system will check the lines based on the initialization, mainly include: is th

7、e connection combination correct, whether there are missed lines, is the power turned on,.if errors were found , the system will sound an alarm, and the alarm led will light up, and pop-up window prompts the user for which line connection is error, and marks the wrong place with different colors boa

8、rd pairs circle; if the connection is correct the output led bulbs flashing, and at this time, users can open the oscilloscope waveform, they can change the course of the amplitude of the waveform, and they can pause it to observe the waveform; in the course of operation, users can save their own in

9、formation (connection, composition and selection of the counter, initialization). open the appropriate file as long as you can. because the user interaction is required when this program is running , so multi-threading technology is needed. there are two worker threads in this procedure. one is used

10、 to deal with light bulbs and off,and another is used for oscilloscope display. key words: virtual experiment, interface 8253, mfc , multi-threading, sql server 20001 问题定义 我的设计题目是:接口8253虚拟实验的研究。 在教学和科研的过程中,经常用到仿真实验,也即虚拟实验。一个好的虚拟实验平台,可以让人通过软件进行仪器的连接、调试得到实验结果,我遇到过类似的实验平台,其中有做的让我记忆犹新的:功能人性化、界面漂亮、最重要的是模

11、拟效果逼真,但是也有让人失望的,例如:进入界面后让人不知从何入手,缺少交互界面,缺少帮助提示,甚至帮助提示具有歧义,在进行实验的时候不知道各个仪器的作用,如果想知道必须切换页面才能出来,在进行仪器连接的时候线路粗糙,实验过程中没有保存功能,出错的话必须重做,缺少撤销或者回退功能,这样的模拟实验环境就失去了它的意义和作用,人们的思维总是被它残缺的功能所打断,不能让人把自己的主要精力放在对实验原理和过程的理解上。这次我所设计的是接口方面的模拟实验,它的主要内容如下:采用c+语言研究虚拟实验中接口8253与cpu引脚之间地址线、数据线和控制线连线技术;包括接口8253和cpu引脚连线的储存表示;连线

12、与否表示;连线正确判断;连线优化。研究虚拟实验中接口8253初始化设计、运行和结果;研究虚拟实验板表示;实验板在移动、放大、缩小以后,维持接口8253与cpu引脚连线;研究接口8253与cpu引脚连线储存和引脚连线恢复。以前做过接口方面的程序设计,因为偏向硬件的原因,所以,我认为有如下几个突出的问题:第一,芯片多,组合多。第二,连线多,线路复杂,容易出错。第三,出错后,不易进行调试。第四,实验过程不清晰易懂。所以,对于模拟实验而讲,就要充分发挥电脑软件的用作,在完成基本要求的同时,尽量解决上述几个问题。2可行性研究2.1 技术可行性从技术的角度来讲,本设计需要的是windows方面的程序设计,

13、而且需要数据库方面的知识。通过分析,需要技术如下:一,加载实验板图片,led图片等需要绘图方面的知识,并且图片需要放大,缩小等;二,连线以及示波器的显示,需要画线方面的知识,并且还需要一些技巧;三,还要涉及到对话框,控件,菜单,工具栏等方面内容;四,数据要存储,所以需要数据库,另外,是针对多个用户操作的,每个用户都可以保存和恢复自己的信息,为了区别各个用户,引导数据库,又要设计到文件方面的操作;五,程序运行过程中用户可以和程序进行交互,所以又要多线程的技术。通过以上的分析,本程序所需要的都不是很艰涩和申奥的技术,只是涉及到会与不会,知道与不知道的问题。在这些内容中,有些是我已经学过的,而大部分

14、是我不会的,因为以前所进行的程序设计大部分是dos下的,所以还是需要很多地方从头开始。有几个地方需要注意,第一,连线与优化,因为在实验板中,8253相关的连线并不规则,所以,连线的时候要进行优化,防止出现混线以及连线传过针脚;第二,在绘图的过程中,要注意进行资源的释放,并且注意绘图的安排,节省资源。总之,从技术的角度而言,没有大的问题。2.2 时间可行性从接到毕业设计题目,到毕业答辩,大概有四个月的时间,除去找工作的时间,应该有三个月的时间来进行毕业设计,所以时间还是很充分的,半个月的时间,足可以把需要的技术弄懂,而一个月的时间是可以把程序给做出来的,剩下的时间可以进行系统的测试,修补完善,以

15、及写论文了。综合分析,这个设计可以很好的完成。3 需求分析3.1功能需求第一,系统应该是多用户的,这里的多用户指的是,每个用户都可以在试验的过程中,保存自己的记录(这些记录包括计数器选择和组合,各个计数器的计数值,针脚之间的连线信息等),进而,当下次使用时,直接恢复。第二,实验板应当可以放大和缩小,可以移动,并且在此过程中,保证长宽比不变。第三,有专门的初始化窗口,用来对计数器进行选择和初始化,计数器的使用方式可以是多种的,不固定,可以任意排列组合,例如:用户可以选择0#,1#,2#计数器,也可以选择2#,0#,1#计数器的组合,或者其中的某两个和某一个。而计数器的初始化应该列出控制字的8个位

16、,可以对每位进行初始化,(因为计数器的初始化包括读写方式,工作方式等,计数方式等,为了方便设计,读写方式可以固定,先读低8位,再读高8位,工作方式固定,按方式3,计数方式按照十进制),并且还要做到,在初始化之后可以对指定的计数器进行再次的修改(主要是计数值)。第四,应当根据计数器的选择和组合情况进行仪器和针脚之间的连线,连线要整洁,最好不要出现混线,并且,线路不要穿过针脚,要保存用户的连线信息,当窗口移动,放大,缩小时连线应当根据窗口进行相应改变,保持和针脚的连接,并且已经连好的线路可以撤销。第五,当根据计数器初始化结果连线结束后,用户便可以编译运行程序了,而在此之前,系统应当可以检查一些基本

17、错误,例如:电源是否打开,连线是否和计数器的选择和组合情况一致等。如果出现错误,则应当具有报错功能,例如:发出报警声,报警led灯闪亮,弹出窗口显示哪些线路连接错误,哪些应该连接在一起,并且最好能在实验板上,用不同颜色的成对圆圈标出应该连在一起的针脚,例如:vcc应该和gate1连接起来,那么vcc和gate1应该用一样颜色的圆圈标识起来,并且这中颜色要和其它的颜色不同,便于用户分别;如果用户连接正确,那么程序就可以运行,输出信号。第六,当以上工作完成后,就应该显示结果了,显示结果的最普通的办法便是灯泡,将输出波形连接到led灯上,根据led的亮灭来显示结果,另外最重要的是要有示波器,将输出结

18、果连接到示波器,这样的话,就非常直观的显示出输出结果了,波形的输出应该是动态的,但是为了方便用户观察,应该有暂停的功能,来使波形暂停。3.2 性能需求第一,应当保证运行的稳定性,不能让用户实验进行过程中,出现死机,程序崩溃等类似的错误,这样用户数据有可能就会丢失;第二,本系统不大,所以,运行过程中,不能占用太多资源。3.3接口要求在本系统中,接口主要指的是用户接口。系统应当清晰易懂,尽量和原实验面板功能贴近,当用户进入系统后,应当知道该做什么,怎么做,一些功能键应该尽量用通用的符号来表示,使用户一看即明。3.3扩展系统有些地方需要扩展的。第一,工作方式、读写方式、计数方式我都是采用的默认的方式

19、,而,这些方式应当可以进行选择,并且实现相应功能,与此同时,示波器的波形也应当根据工作方式而定;第二,应该8个led灯都可以工作,并且,在程序运行过程中,用户可以把输出信号进行切换,例如:现在是用led0显示输出信号,用户可以把led0与输出的连接线撤销,而把输出连接到led1上面,当用户撤销led0的连线时,led0灭,当连接了led1的连线时,led1亮。第三,撤销,在系统中,我做了连线的撤销,但是没做用户操作的撤销(这个撤销功能应该可以撤销用户之前的一系列操作,例如,可以撤销之前的连线信息,也可以在撤消了连线信息后进行恢复等)。4 总体设计4.1方案选取从需求分析阶段,确定了本系统支持多

20、用户的功能之后,我初步设想了两套方案来实现。方案一:用户在进入系统的时候都有自己的一个用户名和用户密码(如果没有可以创建),进入系统首先需要登录,登录成功后,如果要保存数据信息,则以此用户名为索引条件,进行保存,若要恢复,则以此用户名为索引进行查询,引导出此用户名相关的信息,进行恢复。这种方案的好处是,每个用户的信息是相互独立的,用户的数据比较安全。缺点是,比较麻烦,操作不直观。方案二:用户直接进入系统,不需要用户名和密码,进入后用户便可以直接对系统进行操作,当需要保存信息时,用户需要创建一个文件,而这个文件内部却不存放任何信息,用户文件仅仅用来引导数据库,数据库中信息按文件名为索引条件进行保

21、存,需要恢复时,是要打开自己的用户文件即可,数据库便会以此文件名为索引来查询数据,然后进行恢复。这个方案的好处是操作方便,适合用户平时习惯。缺点是,数据相对不安全。综合分析,我选择了第二种方案,因为对于本系统而言,信息安全并不是最重要的因素,另外,别人可以破坏用户数据的前提是,必须知道用户的文件名。另外,也是最重要的因素,使用本系统的大都是教学工作者,而对这些人而言,习惯对他们非常重要,用文件引导,更适合他们平时进行程序设计的方案,保存数据时,就像将程序保存在文件中,而恢复时,就像打开一个程序工作空间一样方便。4.2模块设计系统总体模型接口8253虚拟实验平台视图模块示波器模块计数器初始化模块

22、数据库模块本系统最重要有四大模块,视图模块、计数器初始化模块、示波器模块、数据库模块。视图模块,主要负责以下功能:加载实验板图片,数据初始化,连线的绘制、撤销,连线判断,报警,灯泡的闪亮,数据的保存与恢复。初始化模块,最主要就是实进行计数器的选择和组合,并且进行计数值的初始化。示波器模块,进行示波器的现实,绘制波形。数据库模块,将数据库的操作进行封装,提供给系统接口进行调用。4.2设计数据库本系统涉及到的数据信息主要有:初始化信息(需要连接的针脚在实验板中的位置),用户的计数器初始化信息,用户的连线信息。初始化信息表主要是要保存针脚以及图片的坐标,用来进行进行连线和加载图片的时候使用。考虑到,

23、在程序中使用数字来进行访问那些针脚不方便,于是对针脚的id进行了定义,直接用定义的宏来进行调用。因为数据最后总是读入数组中,为了访问方便(不用查询,直接通过下表来访问),在数据库总id就用宏名称所代表的值来表示,因为涉及到调用针脚名字的地方(纠错,显示阵脚名),所以数据库中还需要有针脚名称这一项。用户的计数器初始化信息表主要用来保存用户对计数器的选择和初始化,首先要有文件名,这用来标识用户,其次要标明选择的是哪个计数器,选择的顺序,计数值,工作方式,读写方式等。选择顺序是很重要的一项,它用来标明计数器的组合情况,这样在程序中就方便进行计数器之间线路的连接了。需要注意的是,本数据库只用来保存被用

24、户选择的计数器信息,没有被选择的不保存。用户连线信息表,用来保存用户的连线信息,连线信息应当有以下几项,当前针脚的id,引脚的名字,所连接到的针脚的id。有了所连接到的针脚的id便可以通过下表快速定位到所要连接到的针脚。便于绘制连线。 初始化信息表tablepinledid用来存放针脚在宏定义中的数字,用来唯一的标识针脚,x,int型,用来存放针脚的横坐标;y,int型,用来存放针脚的y坐标;name,字符串,用来存放针脚的名称。计数器初始化信息表recordcounter其中,username,字符串型,用来存放文件名,用来唯一标识用户,是引导用户数据库的主要项;counter,int型,用

25、来存放被选中的计数器的标号;counternumber,int型,用来存放此计数器的计数值;sequence,int型,用来存放当前计数器被用户组合的序列;rwstyle,int型,用来存放当前计数器的读写方式(默认是先读低8位,再读高8位);workstyle,int型,用来存放当前计数器的工作方式(默认是方式三) 用户连线信息表recordpin 其中,username,char型,用来存放文件名,唯一标识用户,是引导用户数据库的主要项;pinid,int型,用来保存针脚的id ;name,字符串型,用来存放针脚的名字,在必要的时候直接饮用名字;bindtoid,int型,用来存放当前针脚

26、所连接到的针脚的id,通过下表快速定位连接对象。4.3测试计划测试主要围绕计数器的选择进行,针对不同的的组合情况进行测试,测试分别使用三个计数器,两个计数器,单个计数器情况下,系统运行情况;测试连线是否整洁,是否有混线出现,是否穿过针脚;测试纠错功能是否准确和完善,当连线出错时,是否会报错,报错信息是否和计数器的组合相一致,不同的针脚对表示圈颜色是否相异;然后需要测试灯泡的闪亮;测试示波器的运行是否正确,测试运行和停止功能键的作用等。5详细设计加载实验板图片初始化基本数据5.1程序流程图选择并初始化计数器y继续?n 用户连线 检错 y有错误? n运行退出系统5.2数据结构设计好的程序,数据结构

27、非常重要,数据结构设计的巧妙,那么程序处理起来就会方便,也会凸显出来好的算法。我想这就是为什么数据结构要和算法的课程安排在一起讲的原因了吧,二者不分家。5.2.1针脚标识首先,每个针脚应该有自己的标识。针脚信息也应当在程序运行的早期加载进入数组中。为了在数组中定位的方便,那么针脚的标识用数字表示最为方便,因为这样直接可以和数组的下表产生关系。而数字有个特点就是在程序中不容易明白它所代表的意义,因此,用宏对各个针脚进行了定义,为了下表计算的方便,对不同类型的针脚进行了分组(也即数字段)例如:9000-9001用来表示电源开关,9002-9011用来led灯,9022-9035用来表示计数器的针脚

28、等等,这样的话,就可以做到成批处理。5.2.2针脚数据结构在系统中,针脚的计算最多,并且针脚的存储也是用户信息的一个重要组成部分,所以,针脚数据结构的设计非常重要。首先,需要保存此针脚的坐标,所以设置cpoint变量point用来表示其位置;还要有针脚的标识id(int型);针脚的名字name(cstring型)而大部分针脚连接了之后,不能再进行连接,所以,用bool变量 clicked标识针脚是否被点击过;因为涉及到重绘,所以不能将已经连过线的针脚再次连线,用bool型变量binded来标识此针脚是否已经绘制过;应当有其连接到的针脚的id;应当有指向其连接到的针脚的指针。struct pin

29、cpoint point; /坐标int id; /标识bool clicked; /被点击bool binded; /已经和其他针脚连接cstring name; /针脚名字pin * bindto; /指向所连接到的针脚int bindtoid; /所连接到的针脚的id;5.2.3计数器数据结构计数器的使用要涉及到以下几个方面:用bool型变量selected来标识计数器是否被选择;用int型变量rwstyle来标识本计数器的读写方式,默认是先读低8位,再读高8位;用int型变量workstyle来标识计数器的工作方式,默认是方式三;用int型变量cout来标识计数器的计数值;用int型变

30、量sequence来标识此计数器被选择的序列。sequence这一项作用很重要,设计的也很巧妙,这样可以为以后计线路的链接提供方便。struct counterbool selected; /被选中 初始值 false int rwstyle; /读写方式 初始值 -1 int workstyle; / 工作方式 初始值 -1int count; / 计数值 初始值 0int sequence ; /用来记录计数器被选择的次序 初始值 -1 ;5.2.4led灯图片数据结构电源开关打开后,连线出现错误,灯泡显示输出结果情况下需要加载led图片,而图片的加载涉及到图片的加载位置,和图片大小的问题

31、,而只要知道了图片的左上角和右下角的坐标,那么图片的大小自然也就可以计算出来了,于是采用如下的数据结构,用cpoint型变量lefttop来表示图片左上角的坐标,用cpoint型变量rightbootom来表示图片右下角的坐标。struct ledrectcpoint lefttop; /灯泡图片左上角cpoint rightbottom; /灯泡图片右下角;5.3过程设计经过分析,我将程序的功能大体分为了四个模块:试图模块,计数器初始化模块,示波器模块,数据库模块。视图模块,主要负责以下功能:加载实验板图片,数据初始化,连线的绘制、撤销,连线判断,报警,灯泡的闪亮,数据的保存与恢复。初始化模

32、块,最主要就是实进行计数器的选择和组合,并且进行计数值的初始化。示波器模块,进行示波器的现实,绘制波形。数据库模块,将数据库的操作进行封装,提供给系统接口进行调用。因此,主要设计了四个类,来实现相关功能。视图类:virtualexview,封装了实验板相关的操作,包括:加载图片,加载初始信息,连线,响应工具栏,菜单等;计数器初始化类:initialdlg,封装了计数器初始化相关的操作,包括:计数器组合与选择,计数值的设定;示波器显示类:virtualexdlg,封装了示波器显示方面的操作,包括:设定频率和振幅,绘制网格,绘制波形,增大和缩小振幅等操作。5.3.1试图模块通过分析,本系统采用单文

33、档界面(sdi)即可实现。因为系统绘图操作比较多,所以,把程序的核心功能都写在了视图模块里面。视图类主要成员变量的说明因为将视图类作为了系统功能实现的全局区域,所以为了数据传递的方便,一些接口间经常传递的数据需要以成员变量的形式使用。首先,需要保存针脚在实验板中的初始坐标,定义一个pin *类型变量m_ppinarray来指向初始坐标数组。但是,这个坐标是不能参与计算的,因为加载图片进入客户区后,图片的大小,位置都会产生变化,缩放后,图片中,每个点相应的坐标也产生了偏移。而绘图或者连线需要知道当前各点坐标,要计算当前坐标,则需要获得实验板加载后,图片左上角的位置(客户区左上角为(0,0)和图像

34、缩放的倍数,这样可以进行坐标的重定位,不过需要注意的是,必须重新定义一个pin类型的数组用以存放重定位后的坐标信息,成员变量m_ppinlinkedinfo(pin*类型)指向重定位后的坐标数组,成员变量m_scaletimes用来存放实验板图片的缩放倍数,成员变量m_orgoffset(cpoint型)用来存放图片左上角在客户区的位置。坐标重定位公式如下:m_ppinlinkedinfoi.point.x= m_ppinarrayi.point.x/m_scaletimes+m_orgoffset.x;m_ppinlinkedinfoi.point.y= m_ppinarrayi.point

35、.y/m_scaletimes+m_orgoffset.y;在绘制图形的过程中,因为会出现闪屏的问题,而兼容dc和兼容位图可以解决此问题,于是声明了成员变量m_pdcmemory(cdc *型), m_pbitmap(cbitmap *型);而加载了实验板图片后,图片的当前大小也是一个重要的数据,所以用成员变量m_mapsize(csize型)来保存图片当前大小。有三个计数器,为了程序控制的方便采用数组的结构来保存三个计数器的信息,所以定义m_pcounter(counter*型)指向计数器数组。与8253相关的还有以下信息:计数器是否被初始化(用bool型成员变量m_initialed来表示

36、初始值为false,这个时候示波器是没有输出信号的);所连接的时钟(用此时钟的针脚id来表示,int型成员变量m_clkid);所连接的时钟频率(double型成员变量m_clk);传递给示波器的时钟频率(double型成员变量m_tempclk,如果计数器没有被初始化,那么示波器的应当没有输出信号的,但是这个时候时钟频率是确实存在的。);用户选择的计数器个数(int型成员变量m_iniedcounter);此外,对于计数器而言,很重要的一个信息就是计数器的组合选择情况,即谁先谁后,这涉及到后面的针脚连线,怎么来进行判断呢?我在counter数据结构中有个sequence成员变量来标明计数器选

37、择顺序,是为了往数据库中存放数据而设计的,但是如果要在连线的地方使用的话,需要判断三个计数器时间的先后顺序,这样编码会比较复杂,于是我用一个具有三个元素的序列数组来存放计数器的选择情况,第一个元素存放第一个被选择的计数器的下标,以此类推,成员变量m_seque(int*型)指向序列数组。视图类主要函数的设计bool initialmembervar();进行数据的初始化,在构造函数处调用,主要有针脚数组,led数组,计数器数组,计数器序列数组等。virtual void oninitialupdate();这个函数在初次调用ondraw函数之前调用,所以,将实验板图片加载进入内存的处理放在这个

38、函数内部最合适了。virtual void ondraw(cdc* pdc);在需要重绘的地方调用,此函数内部则调用实验板绘制函数,加载灯泡图片,重绘连线等函数。void loadbgmap(cdc *pdc);绘制实验板,因为这个函数经常被调用,而图片加载进入内存只用一次就行了,所以这个函数内部只用来进行绘图,图片的加载则在另外的函数进行。为了做到缩放窗口的时候不闪烁,在此函数内部采用双缓冲的技术。为了使图片美观,采用拉伸绘图的方式,并且保证图片的高宽比不变,让实验板图片始终处于客户区的中间。所以,需要判断当前客户区的高宽比cr和图片的高宽比br之间的大小关系,如果crbr,那么表明客户区比

39、较高,图片需要根据客户区的宽度进行缩放,这个时候图片左上角的坐标计算公式为: m_orgoffset.x = 0; m_orgoffset.y = tempclientheight/2 - height/2( m_orgoffset,图片左上角的坐标,tempclientheight客户区的高度,height图片当前高度);如果crbr则表明客户区比较宽,图片需要根据客户区的高度进行缩放。于此同时,记录缩放比例,计算图片左上角在客户区的坐标,这个时候图片左上角坐标的计算公式为:m_orgoffset.x = tempclientwidth/2 - width/2; m_orgoffset.y=

40、0(其中,tempclientwidth为客户区的宽度,width为图片的当前宽度).然后调用坐标重定位函数,根据缩放比例和图片左上角位置进行坐标重定位。void recalculatepin();坐标重定位,在加载实验板图片后调用此函数,重定位的对象是:针脚坐标,led灯坐标。计算出这些位置的当前坐标。void redrawline();这个函数用来进行连线重绘,在ondraw函数中调用,保证窗口在移动,缩放的过程中连线也进行相应的改变。针脚元素都有一个clicked成员变量,如果此变量为ture,则将此针脚和bindto所指向的针脚连线。并且在连线的时候要注意,不要重复连线,这个可以用bi

41、nded变量来进行标记。即,在clicked为ture且binded为false的针脚才进行连线,然后将binded置为ture;当所有连线结束后,将所有针脚的binded项重新置为false为下次重绘做准备。在连线的时候是有两种情况的,采用的是两种不同的连线方式,一种是非直接连线,一种是pci总线相关的连线采用偏移量方式进行连线。当针脚是计数器相关针脚时,采用前者;如果是pci总线相关的针脚时,采用后者。void indirectline(cpoint pointone,cpoint pointtwo);这个函数用来进行连接计数器,led灯,电源,时钟之间的线路。因为这些线路之间没规则,并且

42、为了美观,要用折线,不能出现混线,连线不能穿过针脚,所以要进行一些计算才能进行连接,并且连接的过程中要出现中间点,中间点的个数也不确定,先和中间点连接在和另外的端点连接,所以函数的名字叫做,即,“非直接连线”。它的实现如下图:afcdeb这种连线的过程如下:要连接a点和b点,则,先用a的横坐标,b的纵坐标得到中间点c,测a,c之间是否有其他针脚,如果没有,则ac间直接连线然后用这样的方法连接cb;如果a,c之间有针脚d,则a的纵坐标增加一偏移量,得到中间点e,同理测ae;再采用同样的方法连接eb,直到从a连接到b。这是一个迭代的过程。void cpubusline(cpoint cpointo

43、ne,cpoint cpointtwo);这个函数负责连接pci总线和计数器之间的连线,因为这些线路很有规则,所以,连接的过程中只要添加一个偏移量,那么就不会出现混线,且不会穿过其它针脚。连接过程如下图所示:aa1bcc1db1d1假设现在连接ab,cd;我设计采用采用两个中间点,连接ab时,第一个中间点a1的纵坐标就是a点的纵坐标,而它的横坐标是个初始值,先连接a和a1,然后用a1的横坐标和b的纵坐标得到中间点b1连接a1和b1,再连接b1和b就可以得到一个折线了。而连接cd的时候,原理和ab相同,只不过,cd的第一个中间点c1的横坐标在a1的横坐标的基础上增加一个偏移量,这样连接的线路便不

44、会重合了。bool otherpininline(cpoint pointone,cpoint pointtwo,int h);在indirectline中被调用,判断点在同一直线上的两个点pointone和pointtwo之间是否有其它针脚,h用来标识当前的两个点是在横线上还是在纵线上。bool isrightpoint(cpoint currentpoint);此函数在onlbuttondown函数中被调用,用来控制连线的总体流程,判断当前点击的位置是否是合法点,对点击的位置进行分组,根据位置的不同进行不同的操作,例如:如果是电源打开按钮,则加载power亮的led图片,如果是连线点则需要

45、判断之前是否有等待连线的位置,如果有,则调用连线函数进行连线,并对针脚的成员信息进行更新(包括已经被连线,连接对象的指针等);如果没有,则当前点的信息需要进栈,等待下个连接点。bool ptinrectangle(cpoint currentpoint,pin *ppin);此函数在isrightpoint中被调用,用来判断鼠标左键所点击的位置是否在ppin*所指向的针脚的附近,如果在则说明左键所点击的位置为合法点,进行接下来的工作,否则不为合法点,不做以后的响应。void loadmybitmap(cpoint pointtopleft,cpoint pointbottomright,int

46、 id);此函数功能:将id所标识的图片加载到左上角为pointtopleft右下角为pointbottomright的位置。在系统中有四个地方需要调用,第一,电源开关按钮的图片,因为随着点击电源开关,开关按钮应当进行上下的移动,而这个功能是通过加载不同的图片来实现的,一张图片开关按钮时在上部,另外一张图片,开关按钮在图片的下部;第二,加载电源led灯,电源开的时候,电源led灯应该亮,所以应该加载电源led亮的图片,电源关的时候应该加载电源led灭的图片而亮和灭是通过颜色的不同来实现的;第三,当出现错误时,加载报警图片;第四,运行后,加载led灯泡图片。void onrbuttondown(

47、uint nflags, cpoint point);这个函数用来撤销连接的线。单击鼠标右键,如果点击的位置是已经连接的针脚的话,就将此针脚的连线撤销。事实上这里是将这两个针脚的连接关系解除,然后调用redrawline函数来实现的。void checkline(cstring & strerror);此函数在运行前被调用,作用是按照用户对计数器的选择和组合情况,检查线路连接是否正确。一般情况下,程序检错和纠错功能的处理都是需要一些技巧的,本系统也是。它需要根据用户对计数器的选择情况而进行检错,而用户的选择和组合情况不是一成不变的,具有多种组合方式,所以,如果用排列的方式的话,代码编写非常不变

48、,于是,我设计一具有三个元素的整形数组m_queue来存放计数器的组合情况,其初始值全为-1,数组的第一个元素存放第一个被选择的计数器的下标,第二个元素存放第二个被选择的计数器的下标,第三个元素存放第三个被选择的计数器的下标,这样,如果没选择的话元素的值就是-1,再用一个变量m_iniedcounter存放被选择的计数器的个数这样会更加方便处理,在进行检错的时候,只用根据m_iniedcounter的值从m_queue的第一个元素开始进行检测即可,m_queue中第一个元素的值作为下标所引用的计数器数的clk连接时钟,out连接到m_queue第二个元素的值作为下标所引用的计数器的clk,以此

49、类推,遇到元素值为-1结束。此外所有被选择的计数器的gate连接vcc,灯泡连接m_queue的最后一个有效元素做为下标所引用的计数器的out。按照这样编码处理就比较容易了,用for循环即可实现。剩余的检测项目就比较简单了,直接罗列即可。当然,遇到了错误应当具有提示功能,用一个字符串变量来存放当前的出错信息,到最后一起在弹出窗口中显示。这样的话,就需要获得每个针脚的名字,而针脚所连接到的对象都是以id来保存的,所以,用函数getname来获得针脚的名字。而每一对儿需要连载一起的针脚用相同颜色的圆圈来标识,这样用户就比较清晰地定位到出错的地方,纠正也比较容易,这个通过每次改变画笔颜色来实现。cs

50、tring getname(int id);获得针脚的名字,id是针脚的标识。因为针脚的id和其在数组中的位置有关系,所以可以直接通过下标来获取针脚名字,不用通过查询。pin * getpt(int id);获得针脚的指针,id是针脚的标识。针脚的id和其在针脚数组中的位置有关系,所以可以直接通过下表来获取针脚名字,不用通过查询。void oneditclearout();将所有的连接信息和计数器初始化信息给清空。void onmenuiteminitial();创建并调用计数器初始化窗口,保存计数器的选择个数,和计数器的选择顺序,以及各个计数器的初始化信息。void onmenuitem32

51、771();创建并调用示波器窗口,根据计数器的选择情况计算输出波形的频率,将输出波形的频率和时钟频率传递给示波器模块。void oneditrun();判断用户连线情况是否有错,如果有错,则进行报错,如果没有错误,则创建并调用灯泡显示线程。static uint ledthreadpro(lpvoid pparam);因为在灯泡显示的过程中用户会有其他操作,例如:调用示波器窗口,停止运行等。所以必须创建一个辅助线程来进行灯泡的显示。辅助线程等待g_eventgo事件的信号产生,在oneditrun函数中,如果没有连线错误,则会将g_eventgo事件发送信号,并且创建线程函数ledthread

52、pro,来显示灯泡。当然既然运行就应当停止。这个线程函数也接受停止信号g_eventstop,此信号在oneditstop函数中发出,当辅助线程函数接受到此信号后,就从循环中跳出,然后线程函数结束。void oneditstop();系统停止用户程序的运行,在此函数内部发出g_eventstop信号。void onfilesave();此函数用来将用户信息(包括计数器选择组合信息,初始化信息,连线信息)保存入数据库,并且产生用户文件。如果此用户文件已经存在,则直接保存入此文件引导的数据项中,如果此用户文件不存在则创建文件,进行保存。保存入数据库的时候,以用户文件名作为主键的一部分来进行保存,方

53、便以后的恢复。用成员变量m_filename,来存放用户文件名。void onfilesaveas();另存为,这个函数的作用是把用户信息另存存放,重新建立一个新的用户文件,用此新的用户名作为主键的一部分往数据库中存入用户数据。用成员变量m_filename,来存放用户文件名。void onfileopen();打开用户文件,打开文件后,用变量m_filename存放文件名,并且以此文件名为查询条件去数据库中查询此用户相关信息,进行恢复。然后按照此信息自动完成计数器初始化和连线,然后用户可以再次基础上进行其他操作。5.3.2初始化模块初始化模块在视图模块的onmenuiteminitial中被

54、调用,此模块用初始化对话框窗口类cinitialdlg进行封装。主要完成计数器的初始化情况,包括计数器的组合选择,设置各个计数器的计数值等。用m_d0-m_d7来保存控制字信息,m_count保存计数值信息,然后传递给试图模块。5.3.3示波器模块示波器模块在onmenuitem32771函数中被调用,主要完成示波器的显示和波形的绘制。功能在cvirtualexdlg类中进行了封装。void loadbgmap(cdc *pdc);加载示波器图片。void setparameter(double f,double a);设置输出波形的幅度和频率。uint setampitudethredpro

55、c(lpvoid pparam);辅助线程函数,用来设置示波器波形的振幅,当接收到g_eventchleamstart信号时,减小振幅,当接收到g_eventchriamstart信号时,增加振幅。当接收到g_eventpause信号时让波形暂停,方便用户的观察。void onlbuttondown(uint nflags, cpoint point);当点击鼠标左键时如果按键的位置在暂停键附近,则发出g_eventpause信号让波形暂停,否则,发出g_eventchleamstar信号,让波形的振幅减小。void onrbuttondown(uint nflags, cpoint point);当点击鼠标右键时,发出g_eventchriamstart信号,让波形的振幅增大。void drawsquarewave(double frequency, double amplitude);绘制时钟信号波形和计数器输出信号波形。时钟信号由成员变量m_clk传递过来,m_clk是一个public类型的成员变量,在cvirtualexdlg对象被创建处(onmenuitem32771函数中)由视图类对象的成员变量m_clk传递过来。输出波形的频率freq

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论