下载

2下载券

加入VIP
  • 专属下载券
  • 上传内容扩展
  • 资料优先审核
  • 免费资料无限下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 创建基于DLL的Proteus仿真模型

创建基于DLL的Proteus仿真模型.doc

创建基于DLL的Proteus仿真模型

雍正
2018-09-08 0人阅读 举报 0 0 0 暂无简介

简介:本文档为《创建基于DLL的Proteus仿真模型doc》,可适用于IT/计算机领域

创建基于DLL的ProteusVSM仿真模型作者:silingsong一、ProteusVSM仿真模型简介在使用Proteus仿真单片机系统的过程中经常找不到所需的元件这就需要自己编写。ProteusVSM的一个主要特色是使用基于DLL组件模型的可扩展性。这些模型分为两类:电气模型(ElectricalModel)和绘图模型(GraphicalModel)。电气模型实现元件的电气特性按规定的时序接收数据和输出数据绘图模型实现仿真时与用户的交互例如LCD的显示。一个元件可以只实现电气模型也可以都实现电气和绘图模型。Proteus为VSM模型提供了一些C抽象类接口用户创建元件时需要在DLL中实现相应的抽象类。VSM模型和Proteus系统通信的原理如下图:绘图模型接口抽象类:ICOMPONENT――ISIS内部一个活动组件对象为VSM模型提供在原理图上绘图和用户交互的服务。IACTIVEMODEL――用户实现的VSM绘图模型要继承此类并实现相应的绘图和键盘鼠标事件处理。电气模型接口抽象类:IINSTANCE――一个PROSPICE仿真原始模型为VSM模型提供访问属性、模拟节点和数据引脚的服务还允许模型通过仿真日志发出警告和错误信息。ISPICECKT(模拟)――SPICE拥有的模拟元件提供的服务:访问、创建和删除节点在稀疏矩阵上分配空间同时还允许模型在给定时刻强制仿真时刻点的发生和挂起仿真。ISPICEMODEL(模拟)――用户实现的VSM模拟元件要继承此类并实现相应的载入数据在完成的时间点处理数据等。IDSIMCKT(数字)――DSIM拥有的数字元件提供的服务:访问数字系统的变量创建回调函数和挂起仿真。IDSIMMODEL(数字)――用户实现的VSM数字元件要继承此类并实现相应的引脚状态变化的判断和回调事件的处理。IDSIMPIN(数字)――数字组件的引脚提供检测引脚状态和创建输出事务事件的服务。IDBUSPIN(数字)――数字组件的数据或地址总线提供检测总线状态和创建总线输出事务事件的服务。IMIXEDMODEL(混合)――同时继承了ISPICEMODEL和IDSIMMODEL元件既有模拟特性又有数字特性。为了让Proteus访问用户模型中的成员函数必须创建用户模型的一个实例。这不能通过类的接口来实现只能通过从DLL中导出几个C函数来实现在用户模型中必须实现这些C函数达到构造和析构用户模型实例的效果。()构造和析构绘图模型实例:IACTIVEMODEL*createactivemodel(CHAR*device,ILICENCESERVER*ils)VOIDdeleteactivemodel(IACTIVEMODEL*model)()构造和析构模拟电气模型实例:ISPICEMODEL*createspicemodel(CHAR*device,ILICENCESERVER*ils)VOIDdeletespicemodel(ISPICEMODEL*model)()构造和析构数字电气模型实例:IDSIMMODEL*createdsimmodel(CHAR*device,ILICENCESERVER*ils)VOIDdeletedsimmodel(IDSIMMODEL*model)()构造和析构混合电气模型实例:IMIXEDMODEL*createmixedmodel(CHAR*device,ILICENCESERVER*ils)VOIDdeletemixedmodel(IDSIMMODEL*model)二、ProteusVSM仿真模型开发流程.绘制元件图形、引脚和相关符号。.制作元件设置元件属性。.用C编写元件实现电气和绘图模型编译生成DLL。.搭建电路仿真测试。二、VSM模型开发实例下面以TGA点阵式液晶显示元件的开发为实例详细讲解开发过程。TGA的pdf手册下载:TGA使用说明书pdf.打开Proteus选择菜单查看>>Snapth选择左边绘图工具栏的Dgraphicsbox绘制如图所示的三个图形。.选择Dgraphicsline给出两条直线设置width为th颜色为灰色。选择Dgraphicscircle给四个角绘制安装孔。选择Markersforcomponentorigin给三个图形分别绘图符号原点(图中红色部分)。.选择Devicepin顺时针旋转度放置个引脚如图所示。GND、VCC、V、Vee、LED的电气类型选择PPPowerPinDI、RW、E、CS、RET、CS、CS的电气类型选择IPInputD~D的电气类型选择IOBidirectional。.右键拖出选择框选择第一个符号选择菜单库>>制作符号命名为LCDAC确定。同理第二和第三个分别命名为LCDA 和LCDA。当用户调用drawsymbol()将绘制LCDAC调用drawsymbol()将绘制LCDA调用drawsymbol()将绘制LCDA。.右键拖出选择框选择符号LCDAC选择菜单库>>制作元件DeviceProperties设置如图点击Next>。跳过封装设置点击Next>。组件属性设置如图点击Next>。选择数据手册(可选)点击Next>。选择器件库点击OK。.打开VC新建工程选择WinDynamicLinkLibrary给工程命名建立空的DLL工程。从Proteus安装目录的INCLUDE文件夹中将VSMHPP复制到当前工程目录新建文件LCDAH和LCDACPP编写如下代码。******************************************************************文件:LCDAH*说明:不支持以下特性*()不支持显示开关控制*()不支持设置显示起始行*****************************************************************#include"vsmhpp"LCD常量#defineLCDBLKNUMlcdblocknumber#defineLCDBLKLENlcdblocklength#defineLCDLINENUMlcdlinenumber#defineLCDLENGTH(LCDBLKLEN*LCDBLKNUM)lcdlength#defineLCDWIDTHlcdwidth#defineBLANKWIDTHthewidthofblank#defineSYMLINEWIDTHthewidthofsymbollineLCD命令掩码#defineCMDMASKxcLCD命令#defineDISPONOFFx开关背光#defineSETSTARTLINExc设置起始行#defineSETXADDRESSx设置X地址#defineSETYADDRESSx设置Y地址延时常量#defineDELAYs#defineDELAYms#defineDELAYus#defineDELAYns#defineDELAYps*LCD元件既有数字电气特性也有绘图特性所以要继承IACTIVEMODEL和IDSIMMODEL*classLCDA:publicIACTIVEMODEL,publicIDSIMMODEL{public:*电气模型成员函数*数字电路总是返回TRUEINTisdigital(CHAR*pinname)当创建模型实例时被调用做初始化工作VOIDsetup(IINSTANCE*inst,IDSIMCKT*dsim)仿真运行模式控制交互仿真中每帧开始时被调用VOIDrunctrl(RUNMODESmode)交互仿真时用户改变按键等的状态时被调用VOIDactuate(REALTIMEtime,ACTIVESTATEnewstate)交互仿真时每帧结束时被调用通过传递ACTIVEDATA数据与绘图模型通信从而调用animate()进行绘图BOOLindicate(REALTIMEtime,ACTIVEDATA*data)当引脚状态变化时被调用主要用来处理数据输入和输出VOIDsimulate(ABSTIMEtime,DSIMMODESmode)可通过setcallback()设置在给定时间调用的回调函数VOIDcallback(ABSTIMEtime,EVENTIDeventid)*绘图模型成员函数*当创建模型实例时被调用做初始化工作VOIDinitialize(ICOMPONENT*cpt)被PROSPICE调用返回模拟电气模型ISPICEMODEL*getspicemodel(CHAR*device)被PROSPICE调用返回数字电气模型IDSIMMODEL*getdsimmodel(CHAR*device)当原理图需要重绘时被调用VOIDplot(ACTIVESTATEstate)当相应的电气模型产生活动事件时被调用常用来更新图形VOIDanimate(INTelement,ACTIVEDATA*newstate)用来处理键盘和鼠标事件BOOLactuate(WORDkey,INTx,INTy,DWORDflags)private:IINSTANCE*instancePROSPICE仿真原始模型IDSIMCKT*cktDSIM的数字元件ICOMPONENT*componentISIS内部一个活动组件对象引脚定义IDSIMPIN*diDIIDSIMPIN*rwRWIDSIMPIN*enEIDSIMPIN*csCSIDSIMPIN*csCSIDSIMPIN*csCSIDSIMPIN*dD~DIBUSPIN*databusDLCD参数BYTExaddrX地址(见手册)BYTEyaddrY地址(见手册)BYTEstatus状态(见手册)BYTEcurblk当前块号(总共分块见手册)BYTEDDRAMLCDBLKNUMLCDBLKLEN*LCDWIDTHLCD显示RAMBOOLnewflag新数据到达标志显示参数BOXlcdareaLCD显示区域floatpixwidth,pixheight每象素对应矩形的宽和高}******************************************************************文件:LCDACPP*说明:不支持以下特性*()不支持显示开关控制*()不支持设置显示起始行*****************************************************************#include<stringh>#include"LCDAh"电气模型的实现构造数字电气模型实例extern"C"IDSIMMODELdeclspec(dllexport)*createdsimmodel(CHAR*device,ILICENCESERVER*ils){授权认证ils>authorize(x,x)版本为returnnewLCDA创建模型实例}析构数字电气模型实例extern"C"VOIDdeclspec(dllexport)deletedsimmodel(IDSIMMODEL*model){delete(LCDA*)model删除模型实例}数字电路总是返回TRUEINTLCDA::isdigital(CHAR*pinname){return}当创建模型实例时被调用做初始化工作VOIDLCDA::setup(IINSTANCE*inst,IDSIMCKT*dsim){instance=instPROSPICE仿真原始模型ckt=dsimDSIM的数字元件获取引脚di=instance>getdsimpin("DI,di",true)di>setstate(FLT)FLOATrw=instance>getdsimpin("RW,rw",true)rw>setstate(FLT)en=instance>getdsimpin("E,e",true)en>setstate(FLT)cs=instance>getdsimpin("CS,cs",true)cs>setstate(FLT)cs=instance>getdsimpin("CS,cs",true)cs>setstate(FLT)cs=instance>getdsimpin("CS,cs",true)cs>setstate(FLT)d=instance>getdsimpin("D,d",true)d>setstate(FLT)d=instance>getdsimpin("D,d",true)d>setstate(FLT)d=instance>getdsimpin("D,d",true)d>setstate(FLT)d=instance>getdsimpin("D,d",true)d>setstate(FLT)d=instance>getdsimpin("D,d",true)d>setstate(FLT)d=instance>getdsimpin("D,d",true)d>setstate(FLT)d=instance>getdsimpin("D,d",true)d>setstate(FLT)d=instance>getdsimpin("D,d",true)d>setstate(FLT)为方便操作将D~D映射为位总线databus=instance>getbuspin("LCDDBUS",d,)databus>settiming(,,)设置时间延迟databus>setstates(SHI,SLO,FLT)设置总线逻辑为,,三态时的驱动状态lcdmodelxaddr=X地址(见手册)yaddr=Y地址(见手册)status=状态(见手册)newflag=TRUE新数据到达标志}仿真运行模式控制交互仿真中每帧开始时被调用VOIDLCDA::runctrl(RUNMODESmode){}交互仿真时用户改变按键等的状态时被调用VOIDLCDA::actuate(REALTIMEtime,ACTIVESTATEnewstate){}交互仿真时每帧结束时被调用通过传递ACTIVEDATA数据与绘图模型通信从而调用animate()进行绘图BOOLLCDA::indicate(REALTIMEtime,ACTIVEDATA*data){if(newflag){有新数据到达data>type=ADTREALcallbackanimate()torefreshlcddata>realval=(float)time*DSIMTICK}returnTRUE}当引脚状态变化时被调用主要用来处理数据输入和输出VOIDLCDA::simulate(ABSTIMEtime,DSIMMODESmode){BYTEdataif(en>isnegedge()){E的下降沿到达if((rw>istate()==SLO)||(rw>istate()==WLO)){RW为低表示写读块选择if((cs>istate()==SLO)||(cs>istate()==WLO))curblk=elseif((cs>istate()==SLO)||(cs>istate()==WLO))curblk=elseif((cs>istate()==SLO)||(cs>istate()==WLO))curblk=elsereturnnotselectblockdata=(BYTE)databus>getbusvalue()读数据if((di>istate()==SHI)||(di>istate()==WHI)){DI为高表示数据DDRAMcurblkxaddr*LCDBLKLENyaddr=data写入数据newflag=TRUE新数据到达标志yaddr=((yaddr)LCDBLKLEN)y地址自动加if(yaddr==)xaddr=((xaddr)LCDLINENUM)自动换行}else{DI为低表示命令switch(dataCMDMASK){caseDISPONOFF:开关背光breakcaseSETSTARTLINE:设置起始行breakcaseSETXADDRESS:设置X地址xaddr=(datax)bit~bitbreakcaseSETYADDRESS:设置Y地址yaddr=(dataxf)bit~bitbreakdefault:break}}}else{E的下降沿到达,RW为高表示读结束databus>drivetristate(time)驱动总线为三态}}elseif(en>isposedge()E的上升沿到达((rw>istate()==SHI)||(rw>istate()==WHI))){RW为高表示读if((di>istate()==SHI)||(di>istate()==WHI)){DI为高表示数据读块选择if((cs>istate()==SLO)||(cs>istate()==WLO))curblk=elseif((cs>istate()==SLO)||(cs>istate()==WLO))curblk=elseif((cs>istate()==SLO)||(cs>istate()==WLO))curblk=elsereturnnotselectblockdata=DDRAMcurblkxaddr*LCDBLKLENyaddrdatabus>drivebusvalue(time,data)输出数据yaddr=((yaddr)LCDBLKLEN)y地址自动加if(yaddr==)xaddr=((xaddr)LCDLINENUM)自动换行}else{DI为低表示命令databus>drivebusvalue(time,status)输出状态}}}可通过setcallback()设置在给定时间调用的回调函数VOIDLCDA::callback(ABSTIMEtime,EVENTIDeventid){}绘图模型的实现Exportedconstructorforactivecomponentmodelsextern"C"IACTIVEMODELdeclspec(dllexport)*createactivemodel(CHAR*device,ILICENCESERVER*ils){ils>authorize(x,x)returnnewLCDA}Exporteddestructorforactivecomponentmodelsextern"C"VOIDdeclspec(dllexport)deleteactivemodel(IACTIVEMODEL*model){delete(LCDA*)model}当创建模型实例时被调用做初始化工作VOIDLCDA::initialize(ICOMPONENT*cpt){获取ICOMPONENT接口和初始化component=cptcomponent>setpenwidth()component>setpencolour(BLACK)component>setbrushcolour(BLACK)获取显示区域component>getsymbolarea(,lcdarea)计算每象素对应矩形的宽和高pixwidth=(float)(lcdareaxlcdareaxBLANKWIDTH*SYMLINEWIDTH*)LCDLENGTHpixheight=(float)(lcdareaylcdareayBLANKWIDTH*SYMLINEWIDTH*)LCDWIDTH}被PROSPICE调用返回模拟电气模型ISPICEMODEL*LCDA::getspicemodel(CHAR*){return}被PROSPICE调用返回数字电气模型IDSIMMODEL*LCDA::getdsimmodel(CHAR*){returnthis}当原理图需要重绘时被调用VOIDLCDA::plot(ACTIVESTATEstate){绘制LCDAC元件基本图形component>drawsymbol()刷新LCD数据显示newflag=TRUEanimate(,)}当相应的电气模型产生活动事件时被调用常用来更新图形VOIDLCDA::animate(INTelement,ACTIVEDATA*data){BOXpixBYTEdat,block,line,byteoff,bitoffif(newflag){当有新数据到达newflag=FALSEcomponent>begincache(lcdarea)打开缓冲component>drawsymbol()显示LCD符号显示各点数据for(block=block<LCDBLKNUMblock){blockfor(line=line<LCDLINENUMline){linefor(byteoff=byteoff<LCDBLKLENbyteoff){lineoffdat=DDRAMblockline*LCDBLKLENbyteoffgetbytedatafor(bitoff=bitoff<bitoff){if(dat(<<bitoff)){bit=pixx=(int)(BLANKWIDTH(block*LCDBLKLENbyteoff)*pixwidth)pixy=(int)(BLANKWIDTH(line*bitoff)*pixheight)pixx=pixx(int)(pixwidth)pixy=pixy(int)(pixheight)component>drawbox(pix)绘制个象素点}}}}}component>endcache()结束缓冲显示数据}}用来处理键盘和鼠标事件BOOLLCDA::actuate(WORDkey,INTx,INTy,DWORDflags){returnFALSE}.搭建电路如下电路新建KeilC工程编写代码测试元件。如下图:LCDA仿真模型和源码下载:

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

评分:

/18

VIP

意见
反馈

免费
邮箱