我花了好长时间设计了一个编程开发环境,在这个IDE中,用户可以写MCS51单片机程序,可以写AVR程序,可以写电脑上位机控制程序(生成exe),还可以写一种虚拟机程序(类似java),在这些上层的诸多的处理器类型之下,我给这个语言设计了一个唯一的标准化语法,或者说,这个语言移植到各类处理器中。
我的毕业设计就是用这个开发环境设计的,全部程序写在一个记事本文件中(超萌小地鼠.txt)。用编译器打开这个记事本文件,点击编译按钮,生成3个我们最终需要的目标文件。其中两个是hex文件下载到单片机中,不过上位机程序编译之后不是生成exe文件,而是生成一个V扩展名的文件:超萌小地鼠控制器.V 。这个类似于java的字节码文件,需要在一个虚拟机中运行。和java有一点不同的是,java的编译器(JC)和虚拟机(JVM)是分开的,而我的设计中把编译器和虚拟机都集成到这个开发环境中,因此编译生成的V文件,在打开方式中选择编译器的文件名目录,或者点击编译器的“打开文件”这个按钮也可,由于是V文件,编译器打开后会自动调用虚拟机运行这个文件。程序运行后出现一个窗体,这个窗体可以接受电脑键盘按键事件,并控制远程小地鼠相应运动。
以下我从几个方面说明一下这个开发环境和编程语言。
1 程序编辑器
程序编辑器分为两种模式——文本模式和图形模式。图形模式主要是实现一些端口的连接配置,例如做个单片机控制1602液晶屏的实验,那么液晶屏的这些端口和单片机的连接方式就可以在图形界面拖出相应的模块,再用鼠标连好,然后切换到文本模式写程序。在文本模式下,编译器可以对用户输入的关键字进行着色,还有自动格式对齐、转换注释等基本功能。上面说到可以在图形界面中拖出一些模块,如1602液晶屏,4位数码管模块等,我们暂时先把这些模块称作“组件”,编译器自带一个组件库、一个组件查看器和一个组件设计器。
1.1 组件查看器
通过组件查看器浏览组件库中的组件,浏览界面的左部分是一个树形列表,表示组件库中的各个组件,当点击树形列表的某个节点时,在右侧的图形区显示出这个组件的外形,包括它的背景图片,它所拥有的端口等。如果当前在图形模式下,那么单击这个库组件就可以添加到当前的程序中。
![]()
1.2 组件设计器
用户可以运行组件设计器来设计一个新的组件并添加到组件库中,设计一个新组件只需要一个背景图片,一般可以用相机把某个实际的电路板拍下来,留出电路板主体部分作为组件的背景,另外电路板上会有一些插针端口,在这些端口上放置“虚拟端口”,虚拟端口就是以后可以用鼠标连线的点。下图正在设计一个4位数码管组件,图中已经放置了两个虚拟端口,虚拟端口的放置点最好和实际电路板的插针端口位置一致,这样也能方便实物电路的连线,当在电脑上连好虚拟导线之后,可以照着这个图在实物电路板上进行相应的实际连线,用杜邦线连接等等。
![]()
![]()
其实到这里肯定有人能看出来,这套开发环境系统是软件和硬件结合起来的,假设用户事先拥有一大堆的各种电路板组件(实物),然后到开发环境的组件库中选择自己需要的组件,在图形界面把这些组件连好,对应的实物组件也用导线连好,然后就可以切换到文本模式写程序直接控制各个组件工作,至于每个组件的端口配置,编译器会根据用户的连接自动产生相应的配置代码,相当于编译器自动生成:
#define RS P1.0
#define RW P1.1
#define E P1.2
#define DATA P2
#include LCD1602.h
然后转到文本模式之后,就可以直接写这样的控制语句控制屏幕显示了:
液晶屏 初始化,
液晶屏 第一行显示 “Hi, Kuai Qi Chuang”,
液晶屏 第二行显示 “Zai Shui Hui er”,
2 虚拟机
虚拟机其实是这个编译器支持的一种处理器类型,编译器为它生成机器代码。目前编译器支持的处理器类型有:AVR,MCS51,PC80X86和VM。设置处理器类型的语法如下(选自小地鼠程序的第5行,本文最后有程序的完整附录):
ACI cpu = ACI cputype VM 小地鼠控制器,
其中VM表示设置目标芯片类型为虚拟机类型,生成的V文件名称是“小地鼠控制器.V”。如下为设置目标芯片为AVR:
ACI cpu = ACI cputype MEGA32 小地鼠控制器,
如果一段程序目标芯片设置为AVR或MCS51时,那么生成hex文件;目标芯片为PC80X86时生成exe文件,可以双击运行;目标芯片为VM(虚拟机)时生成V文件,目前这个V文件还只能在编译器自带的虚拟机中运行,以后也可以在单片机中加载一个虚拟机去解释执行这些V程序。和这个虚拟机对应的有一个调试器,在调试器界面上可以控制虚拟机全速运行,单步运行或定时运行。
上面这些是软件意义上的虚拟机,这个系统还有另一形式的硬件虚拟机,也可以看成是一种硬件端口模拟器。比如说,用户把LCD1602,几个按键和一个DS1302时钟模块连接到这个硬件端口模拟器上(可以由单片机实现),用户可以在其他的单片机上控制这个系统工作,当然两者之间会有某种通信连接,无线或串口等,但又不是普通的双机通信,……哎 这个我也说不清楚了,主要是没有一个看得见的实例展示一下,大家会误以为只是普通的单片机通信而已,其实不是的,这个语言带有内置的“虚拟端口”机制实现这个的。主要是没有现成的实例…… 这个需要去工厂做电路板的,现在没时间,也没钱。等以后做一个端口模拟器出来我再好好图文并茂地讲解一下这个“硬件虚拟机”,真的很酷~~ 哎,现在说不清楚…… 呜呜
3 ISP下载器
上面我们的程序都写完了,就可以编译下载到芯片中了。我在这个开发环境中集成了一个ISP下载器,目前支持AT89S51,S52,MEGA8,MEGA16和MEGA32。当我们写完一个程序单击编译按钮,生成hex文件之后,再单击ISP下载器的按钮,就出现下载器界面,并且它自动装载刚才生成的hex文件,用户只需要点击“自动下载”即可。“自动下载”包含一系列操作,具体跳过哪个步骤可以用户设置,按顺序包含如下步骤:
1 文件改变重载
2 比较芯片ID
3 擦除Flash
4 检查空片
5 写入Flash
6 校验Flash
每次单击“自动下载”都会依次执行这些操作。也可以取消选中第4和6项,也就是跳过这两项,因为执行擦除之后芯片一般就是空的了,而且写入的出错几率也很小,也就不需要校验了。选中第1项时,每次目标文件改变了,比如用户重新点击编译按钮更新hex文件等,反正只要文件发生变化,下载器都会自动重新加载目标文件,这样就省去了每次下载程序都要手工打开文件这一步了。
这个是下载器的界面:
![]() |