⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 4.虚拟仪器驱动程序.txt

📁 虚拟仪器软件的介绍
💻 TXT
📖 第 1 页 / 共 5 页
字号:
0xBFFC0D28 */
#define prefix_INSTR_ERROR_PARAMETER18  (_VI_ERROR+0x3FFC0D29L)/* 
0xBFFC0D29 */

#define  prefix_TIMEOUT_MAX  2147483647
#define  prefix_TIMEOUT_MIN  0

/* All function with the prefix of _VI_FUNC */
/* ALL pointer type parameters with the prefix of _VI_FAR */

/* required plug and play functions from VPP-3.1*/
/* Common Functions in all virtual instrument drivers */

ViStatus _VI_FUNC prefix_init (ViRsrc InstrDesc, ViBoolean id_query,
                ViBoolean do_reset, ViPSession vi);
ViStatus _VI_FUNC prefix_close (ViSession vi);

ViStatus _VI_FUNC prefix_reset (ViSession vi);

ViStatus _VI_FUNC prefix_selfTest (ViSession vi, ViPInt16 test_result,
                                    ViChar _VI_FAR test_message[]);

ViStatus _VI_FUNC prefix_errorQuery (ViSession vi, ViPInt32 
error_number,
                ViChar _VI_FAR error_message[]);

ViStatus _VI_FUNC prefix_errorMessage (ViSession vi, ViStatus 
error_number,
                ViChar _VI_FAR message[]);

ViStatus _VI_FUNC prefix_revisionQuery (ViSession vi, 
        ViChar _VI_FAR driver_rev[], ViChar _VI_FAR instr_rev[]);

/* prefix other standard functions */

ViStatus _VI_FUNC prefix_dcl(ViSession vi);

ViStatus _VI_FUNC prefix_timeout(ViSession vi, ViInt32 timeOut);

ViStatus _VI_FUNC prefix_timeout_query(ViSession vi, ViPInt32 timeOut);


/* Used for "C" externs in C++ */
#if defined(__cplusplus) || defined(__cplusplus__)
}    /* end of "C" externs for C++ */
#endif 

#endif /* prefix_INCLUDE */
2、 参考相关例程法:在仪器驱动程序设计过程中,也可以找出与本模块类似或同
类的驱动程序源代码作为参考。需要声明的是,参考不是抄袭,这种允许源代码之
间的参考正是VPP规范所提倡的开放性与兼容性的要求。仍以可编程数字输入/输出
模块dio开发为例,可以找到对应的HP公司的相关产品hpe1458或Tek公司的相关产
品VX4802,阅读hpe1458与VX4802仪器驱动程序源代码,在其上面进行修改(修改
的依据是模块功能的调整),就会大大提高本仪器驱动程序的正确性与效率。在这
种参考相关例程法中,理解自己要实现的功能任务与理解参考源代码是同样重要的
,当可参考的例程(指产品化的例程)与本仪器驱动程序越接近时,这种方法越有
效,而当需要设计一个特定的仪器模块而无法找到合适的参考例程时,只能找到越
相近的例程越好。因此,参考例程的质量与风格会直接影响所设计的驱动程序的质
量与风格的。
3、 以上两个方法事实上采用的是手工编写的方法,在仪器驱动程序中是否可以引
入自动化生成工具,是设计人员进一步追求的目标。近年来,以NI公司为代表的
IVI (Interchangeable Virtual Instruments)协会推出的IVI规范,提出了可换式
仪器驱动程序的生成方法,为建立以面向对象技术为基础的仪器驱动程序的设计提
出了新思路。然而,根据实际研究,发现它能实现的可互换式仪器驱动程序只是有
限的几个,生成方法也比较复杂,工作量不小,其推广性并没有如它宣传的那么大
,并没有被业界所广泛接受。在国内,电子科技大学CAT室也推出了表格化设计的
虚拟仪器库,也推动了仪器驱动程序设计自动化。在本节中,同样基于面向对象程
序设计的技术,提出了一个虚拟仪器驱动程序生成工具的实现方法。
本设计模型采用了自顶向下层层细化的设计思路,在所有仪器的顶层,是一个基类
,定义为CInstrument,在基类中定义了基本成员变量与成员函数,所有成员函数
以纯虚函数的形式提供函数原型,不给出函数实体。在这些成员函数中,定义的均
是最基本的通用函数。
从基类CInstrument开始派生出基本仪器类型类,共分为VXI消息基器件类
CMessageVXI、VXI寄存器基器件类CRegisterVXI、GPIB器件类CGPIB及串行接口仪
器类CRS232,各仪器类均继承了基类的成员变量与成员函数,并以虚函数形式重写
成员函数并添加各自的成员函数,以供下一层类调用。在基本仪器类型类往下再进
行类派生,生成了具体仪器类,如VXI消息基器件派生出万用表器件类CVXIDMM与数
字信号发生器类CVXISIGP等,各自在继承了上层类的基础上加入了各自新的成员变
量与成员函数,成员函数仍以虚函数的形式给出。这样当仪器驱动设计人员进行程
序设计时,先确定自己仪器的类型,找到自己的上层类,如可编程数字输入/输出
模块dio找到了VXI寄存器基器件类下派生的输入/输出模块类作为派生类,就可以
得到了输入/输出模块的通用功能函数,这比第一种核心模块法提供的核心模块程
序要进步得多。利用虚拟仪器驱动程序生成工具,可以生成虚拟仪器驱动程序的大
部分代码,其它新的功能函数的添加与修改,也可以在这个生成工具中进行。最后
,利用转换工具,将特定的类定义转换成虚拟仪器驱动程序形式进行封装,可以提
高开发效率。仪器驱动程序的类派生结构图如图4.10所示。
图4.10 仪器驱动程序类派生基本结构图
根据生成工具,可以完成一部分编写工作,但是完全由计算机自动产生虚拟仪器驱
动程序的所有源代码,无乎是不可能,也是没有太大的实际效益的。真正的编写工
作是尽可能地利用现有的基础与工具,但必须意识到整个开发与调试工作还是由设
计人员一步步来完成的。在实际编写过程中,寄存器基器件的编写比消息基器件的
编写难度更大,更深入到仪器内部,因此依靠自动生成工具生成困难也就更大。如
一个简单的可编程数字输入/输出模块通讯协议中的握手模式与延时时间的设置,
使用消息基器件操作方式,因为只涉及两个SCPI命令,SCPI命令格式如下:(
[SOURce:] Digital: DATAn [:type]: HANDshake [:Mode] <mode>)与(
[SOURce:] Digital: DATAn [:type]: HANDshake: Delay <time>),所有输入/输
出模块的操作格式是一致的,可以用工具继承生成,但对于寄存器基编程方式而言
就会涉及到模块内部寄存器的读写操作,编程会复杂得多,因此用生成工具来完全
自动生成是不可能的。例程如下所示。
/*——————————————————————————————————
 * 函数名:zde1458_handshake
 * 函数描述:设置所有端口的握手模式与延时时间
 * 参数描述:
 *   输入参数:
 *       ViSession vi   :仪器句柄
 *       ViInt16 mode   :握手模式
 *          宏  名                       值      说明
 *          zde1458_HANDSHAKE_NONE        0      None
 *          zde1458_HANDSHAKE_LEAD        1      Leading
 *          zde1458_HANDSHAKE_TRA         2      Trailing
 *          zde1458_HANDSHAKE_PART        3      Partial
 *          zde1458_HANDSHAKE_PULS        4      Pulse
 *          zde1458_HANDSHAKE_STR         5      Strobe
 *       ViReal64 delay :握手延时时间
 *          MAX = zde1458_MAX_HAND_DEL   15.0000E-3(15ms)
 *          MIN = zde1458_MIN_HAND_DEL   2.0E-6(2us)
 *          延时值与端口延时寄存器值关系:
 *              2us--15us    ===>0x20--0xf0
 *              20us--150us  ===>0x21--0xf1
 *              200us--1.5ms ===>0x22--0xf2
 *              2ms--20ms    ===>0x23--0xf3
 *   输出参数:
 *       无
 *   返回值:
 *       VI_SUCCESS     :握手模式与延时设置完成
——————————————————————————————————*/
ViStatus _VI_FUNC zde1458_handshake(ViSession vi,
                  ViInt16 mode, ViReal64 delay)
{
    ViStatus errStatus;
    ViUInt8 handshake_mode_reg;
    ViUInt8 handshake_delay_reg;
    ViAddr address;
    
    errStatus = VI_SUCCESS;
    
    /* 检查输入握手模式是否合法 */
    if ((mode < 0) || (mode > 5))
    {
        return VI_ERROR_PARAMETER2;
    }
        
    /* 检查输入延时值是否超界 */
    if ((delay < zde1458_MIN_HAND_DEL) ||
        (delay > zde1458_MAX_HAND_DEL))
    {
        return VI_ERROR_PARAMETER3;
    }

    /* 决定握手模式与握手延时寄存器 */
    zde1458_handshake_reg(mode, delay, &handshake_mode_reg,
                          &handshake_delay_reg);

    /* 映射内存空间 */
    errStatus = viMapAddress(vi, VI_A16_SPACE, 0x00, 0x40, 
                             VI_FALSE, VI_NULL, &address);
    if (errStatus < VI_SUCCESS)
    {
        return errStatus;
    }

    /* 端口0-3 */
    viPoke16(vi,(ViAddr)((ViUInt8 *)address+card_stat),bank_0);
    /* 设置握手模式 */
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_hand_0), 
handshake_mode_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_hand_1), 
handshake_mode_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_hand_2), 
handshake_mode_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_hand_3), 
handshake_mode_reg);
    /* 设置握手延时值 */
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_del_0), 
handshake_delay_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_del_1), 
handshake_delay_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_del_2), 
handshake_delay_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_del_3), 
handshake_delay_reg);

    /* 端口4-7 */
    viPoke16(vi,(ViAddr)((ViUInt8 *)address+card_stat),bank_1);
    /* 设置握手模式 */
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_hand_0), 
handshake_mode_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_hand_1), 
handshake_mode_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_hand_2), 
handshake_mode_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_hand_3), 
handshake_mode_reg);
    /* 设置握手延时值 */
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_del_0), 
handshake_delay_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_del_1), 
handshake_delay_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_del_2), 
handshake_delay_reg);
    viPoke8(vi,(ViAddr)((ViUInt8*)address+port_del_3), 
handshake_delay_reg);

    /* 端口8-11 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -