ADCardX.OCX 控件使用说明

返回
 

VB下控件使用方法

本控件可在 Windows 95/98 下支持 ActiveX 的任何开发环境中使用,如 Visual Baisc 、 Delphi 、 C++Builder 、 Visual C++ 等。它把对北京瑞博华控制技术有限公司开发的各类 AD 采集板的控制命令以用户易于理解和使用的方式提供给用户,使用户以简单、高效地方式操作 AD 板,而不用处理底层的硬件细节。而且,本控件可支持本公司的系列 AD 板,即同一个控件和同一套用户程序可支持不同的 AD 板。

本控件使用方式极为简单,现以 VB 开发环境为例说明其使用方法:

首先,在 VB 环境中先引用此控件 ( 在 Windows 95 系统目录下,文件名 ADCardX.OCX ,控件类型为 ADCardX) ;

其次,在用户的 Form 中,放置此控件,缺省控件名为 ADCardX1 ,它的界面比较简单,直接显示本机器中所安装的 AD 采集板的名称;

然后,可在属性窗口中设置 AD 板的各种属性,如 I/O 基地址、采样频率等,或在程序中直接用代码设置各属性。

然后,在程序中操作 AD 板的过程如下:

第一步先要调用 Initial() 方法初始化 AD 板,返回值告诉用户初始化是否成功 (=0 即失败 ) 。

第二步要调用 StartIntr() 方法或 StartSnapshot() 方法让 AD 板开始采样;

第三步,为了得到采样结果,调用方法 GetADResult() 或 GetADResultRecent() 或 GetSnapshot() ,就直接把采样结果存放在用户指定的数组中,然后用户可以直接在此数组中使用 AD 采样结果了,如存盘、图形显示或进行别的处理。

第四步, AD 采样结束时,调用 StopIntr() 或 StopSnapshot() 方法使 AD 板停止工作。

最后,需要说明的是本控件有两种工作方式:

一种是多缓冲区方式,用 StartIntr() 方法启动。此时系统 ( 驱动程序 ) 内部开有 NumInnerBuf 个缓冲区,每个缓冲区可存放 NumChn 个通道、每通道 SampPerChn 个 AD 采样结果。 AD 采集的结果顺序存放在各缓冲区中, GetADResult() 方法就顺序地取出 ( 最先 ) 一个放满采样结果的缓冲区的内容 ( 进行过此操作后此缓冲区又可接收新的采集结果 ) ,而 GetADResultRecent() 方法直接取最后 ( 新 ) 一个缓冲区的内容 ( 进行过此操作后所有缓冲区又可重新接收新的采集结果 ) 。在这种方式下,存放有 AD 采集结果的缓冲区数目可用方法 ResultBuf() 进行查询,而且,在设置属性 EnableNotify 为 True 时,每一个缓冲区满时会给用户程序发送事件 Notify() ,用户可在这个事件响应函数中进行取 AD 缓冲区的工作。此方式用 StopIntr() 停止。若没有及时从缓冲区取采样结果,而使所有缓冲区都满时,此后 AD 采样结果就将丢失,直到有缓冲区被 GetADResult() 或 GetADResultRecent() 释放、可存放新的采样结果为止。此工作方式适宜于连续记录 AD 采集结果。连续两次成功地 GetADResult() 取得的 AD 结果在时间上不会重叠,之间是否丢失采样结果,要看返回结果的序列号 ( 结果数组的第一个值,为无符号短整数 ) 是否递增加一 ( 注意, 0xFFFF 加一后会变成 0) 。只增一,说明两缓冲区在时间上是连续的。在采样率较低时,通过多缓冲区方式,有可能连续地记录、处理、保存长时间的 AD 结果。

另一工作方式为单缓冲区方式,用 StartSnapshot() 方法启动,它始终不断地往缓冲区中存放 AD 结果,缓冲区大小为 NumChn 个通道,每通道 SampPerChn 个点。方法 GetSnapshot() 从此缓冲区中得到所有通道、最新指定个点 ( 点数在方法的参数中指定 ) 的采集结果 ( 的快照 ) ,这时 EnableNotify 属性值一般应置为无效。此工作方式由命令 StopSnapshot() 终止。此工作方式适宜于示波器方式,可随时得到最新的采集结果 ( 的快照 ) 。但两次 GetSanpshot() 取得的结果在时间上可能有重叠或丢失,相对时间关系不能确定,或者通过函数 GetSnapshot(ByRef ADBuf as Integer, ByVal SampPerChn0 as Long, ByRef SampPtr as Long) 返回的 SampPtr 值和返回的 ADBuf 第一个元素所代表的系列号来求出。

属性和方法说明

重要的属性含义如下,按名称、类型、含义进行介绍:

IOBase: Integer 。指定 AD 板 I/O 基地址。

IRQNum: Integer 。指定 AD 板占用的 IRQ 值 (0-15) 。

PhysAddr: Long 。指定 AD 板占用的 RAM 地址。

DMAChn:Integer 。指定 AD 板使用的 DMA 通道号。

NumInnerBuf: Integer 。指定多缓冲区方式下内部缓冲区个数。

SampPerChn: Long 。指定每个缓冲区内可存放的每通道采样点数。

BegChn: Integer 。在单通道采集方式下,指定采集的通道号;多通道方式下,指定起始通道号;在既有模拟通道又有开关量通道的板上, BegChn 表示模拟通道道第 BegChn 及之后就存放开关量通道的值。注:有些 AD 板 BegChn 有定义,有些 AD 板可为任意值而无任何作用。

NumChn: Integer 。指定要采集的总通道数。

FrqSamp: Long 。指定的名义采样频率。而每通道实际采样频率可通过 CHnFrq 方法获得。

FrqFilter: Long 。指定内部滤波器截止频率。对有些 AD 板此参数无作用。

AmpGain : Integer 。指定板上程控放大器的增益。一般可为 1 , 2 , 4 , 8 , 10 , 100 , 1000 。对有些 AD 板此参数无作用。

EnableNotify: Boolean(True or False) 。指定多缓冲区方式或单缓冲区方式下是否触发事件 Notify 。

NofityLength : Long 。指定单缓冲区方式下各通道采集 NotifyLength 个数时触发一个 Notify 事件。注:多缓冲区方式下,每缓冲区满就触发一个 Notify 事件,只要 EnableNotify=True 。

ADCardName: String( 只读 , 并显示在控件本身上 ) 。返回 AD 板类型 ( 名称 ) 。

ResultBuf: Integer( 只读 ) 。返回已有采集结果的缓冲区数目。仅多缓冲区方式下有意义。

Visible: Integer(better set to False) 。指定控件是否可件。为美观起见一般设为不可见。

MaxChn: Long( 只读 ) 。返回当前采集板支持的最多通道数 ( 含开关量通道,每 16 个开关量占一个模拟量的内存地址 ) 。

MaxBinChn : Long( 只读 ) 。返回当前采集板支持的最多开关通道数。

VZero: Single( 只读 ) 。返回当前采集板采集结果的格式:在 16 位无符号短整数表示的 AD 值中,电平 0 对应的值。

VMax: Single( 只读 ) 。返回当前采集板采集结果的格式:在 16 位无符号短整数表示的 AD 值中,最高电平 (+5V) 对应的值。

注:由上可知:对 AD 采集结果 ADBuf(?) ,它实际采用偏移二进制编码,它对应的实际电压为 ( 单位: V) :

(ADBuf(?)-VZero)/(VMax-VZero)*5

但由于 VB 不支持无符号整数 ( 只能按有符号整数对待 ) ,对 16 位 AD 芯片 (VZero=32768., VMax=65535.) ,要得到电压值,需用如下公式:

If (ADBuf(1) > 0) Then

V = (ADBuf(1) - VZero) / (VMax - VZero) * 5

Else

V = (65536 + ADBuf(1) - VZero) / (VMax - VZero) * 5)

End If

重要的方法 :

ChannelFrq(ByVal NumChn As Long, ByVal FrqSamp As Long) as Single: 返回值的含义为:若属性 NumChn( 仅指模拟通道数目 ) 和 FrqSamp 置为本方法指定的参数时每通道的实际采样率 ( 单位: Hz) 。

Initial() as integer :初始化 AD 板。 AD 板存在,且属性 IOBase 、 IRQNum 、 PhysAddr 正确时返回常数 ADCard_Success ,否则返回 ADCard_Error(=0) 。

StartIntr() as Long :启动多缓冲区工作方式。成功时返回每缓冲区的大小 ( 字节数 ) ,这时,用 GetADResult() 或 GetADResultRecent() 时用到的缓冲区大小应大于或等于此值 ( 字节数 ) 。失败时返回 0 。

StopIntr() as Integer :停止多缓冲区工作方式。

StartSnapshot() as Integer :启动单缓冲区工作方式。成功时返回内部缓冲区的大小 ( 字节数 ) 。失败时返回 0 。

StopSnapshot() as Integer :停止单缓冲区工作方式。

ResultBuf() as Integer :返回多缓冲区方式下已有采集结果的缓冲区数目。

GetADResult(ByRef ADBuf as Integer) as Integer :在多缓冲区方式下把最先的一个有采集结果的缓冲区内容拷贝到用户数组 ADBuf 中。并释放当前缓冲区。

这时用户数组尺寸要求大于 SampPerChn*NumChn+1 个短整数。

GetADResultRecent(ByRef ADBuf as Integer) as integer :在多缓冲区方式下把最新的一个有采集结果的缓冲区内容拷贝到用户数组 ADBuf 中,并释放所有内部缓冲区。

这时用户数组尺寸要求大于或等于 SampPerChn*NumChn+1 个短整数。

GetSnapshot(ByRef ADBuf as Integer, ByVal SampPerChn0 as Long, ByRef SampPtr as Long) as Integer :

在单缓冲区方式下把最新的采集结果 ( 仅 SampPerChn0 个点、 NumChn 个通道 ) 拷贝到用户数组 ADBuf 中。最新数据在内部缓冲区中的位置返回在 SampPtr 中,它的范围为 0~SampPerChn-1 ,而内部缓冲区已被覆盖过几次,这值返回在数组 ADBuf 的第一个短整数中,即 SeqNo 中,用户可由这两个参数确定两次 GetSnapshot 取的结果的相对时间关系。要求 SampPerChn0<SampPerChn 。

这时用户数组尺寸要求大于或等于 SampPerChn0*NumChn+3 个短整数。

IOCtl(ByVal InSize as Long, ByVal InBuff as String, ByVal OutSize as Long, ByVal OutBuff as String) as Long: 和 AD 板专用数据交换接口。

IOCtlByte(ByVal InSize as Long, ByRef InBuff as Byte, ByVal OutSize as Long, ByRef OutBuff as Byte) as Long: 和 AD 板专用数据交换接口的另一种参数类型。

InportB(ByVal Port as Integer) as Integer :单字节端口读。辅助工具接口函数。

Inport(ByVal Port as Integer) as Integer :单字端口读。辅助工具接口函数。

InportDW(ByVal Port as Integer) as Long :双字端口读。辅助工具接口函数。

OutportB(ByVal Port as Integer, ByVal Value as Integer) :单字节端口写。辅助工具接口函数。

Outport(ByVal Port as Integer, ByVal Value as Integer) :单字端口写。辅助工具接口函数。

OutportDW(ByVal Port as Integer, ByVal Value as Long) :双字端口写。辅助工具接口函数。

AD缓冲区格式说明

返回 AD 结果格式说明:

方法 GetADResult() 、 GetADResultRecent() 、 GetSnapshot() 把 AD 采集结果拷贝在用户数组 ADBuf() 中, ADBuf 的格式定义为:

Dim ADBuf(NumChn*SampPerChn+1) as Integer

则: ADBuf(0) 为此次结果的序列号:在多缓冲区方式下,每个缓冲区的序列号按采集时间先后顺序增一,若缓冲区满而丢失数据时此值会增加以表示丢失了多少缓冲区;在单缓冲区方式下,表示此次快照是系统内部缓冲区被覆盖 ( 填满 ) 多少此时的结果。此值是按无符号短整数递增的,在 65535(=0xffff) 后会反转为 0 的。

ADBuf(1 至 NumChn*SampPerChn) 顺序存放各通道、各时刻的采样值。第 n 通道 (n=0 至 NumChn-1) 、第 m 时刻 (m=1 至 SampPerChn) 就存放在数组单元 ADBuf((m-1)*NumChn+n+1) 中,即 ADBuf(1) 存放第 0 通道第 1 时刻的值, ADBuf(2) 存放第 1 通道第 1 时刻值, ...... , ADBuf(NumChn) 存放第 NumChn-1 通道第 1 时刻的值, ADBuf(NumChn+1) 存放第 0 通道第 2 时刻的值, ...... 。对 12 位 AD 板,采样结果为偏移二进制编码,即: 0 表示最低电压值 ( 如 -5V) , 2048(=0x800) 表示 0 电压, 4095(=0xfff) 表示最高电压 ( 如 +5V) 。具体电压值可由属性 VZero 和 VMax 转换出。

若 AD 板既支持模拟量,又支持开关量,则在等价的 NumChn 个总通道中,通道 0 至 BegChn-1 为常规的模拟量,通道 BegChn 至 NumChn-1 为组合的开关量通道,每 16 个开关量通道占 1 个模拟量通道的缓冲区 ( 即每模拟通道占 1 位,且通道 0 占短整数的 bit 0, 通道 15 占短整数的 bit15 ,而每模拟通道占 16 位 ( 无符号短整数 ))

杂类说明

1. 重要的事件 :

Notify(): 在多缓冲区方式下,每一个内部缓冲区填满采集结果时调用一次此事件。

2. 重要的常数定义 :

ADCard_Error = 0

ADCard_Success = 1

3. 注意事项 :

此控件需要在 \Windows\System 目录下的 ADCard.DLL 和相应的 VxD 驱动程序支持。

简单的 VB 示例

一个简单的使用示例如下 (VB5):

建立一个窗体 (Form) ,在其上定义几个控件: Label1, Label2, ADCardX1,Command1,Timer1

拷贝如下代码,就建立起一个简单但完整的 AD 采集程序: ( 点击命令按钮就开始采样,再点击就停止。采样结果显示在 Label1( 表示缓冲区序列号 ) 和 Label2( 表示第 iChn 通道、第 iSamp 点的采样值 ) 上 ) 。注意,在 Form_Load 中设置 WorkMode = 0 表示多缓冲区工作方式,否则为单缓冲区方式。代码如下:

Dim ADBuf() As Integer 'size-variable array

Dim Working As Integer

Dim WorkMode As Integer

Const NumChn = 1

Const SampPerChn = 300

'range for iChn: 0 -- NumChn-1

'range for iSamp: 1--SampPerChn

Const iChn = 0

Const iSamp = 1

Private Sub ADCardX1_Notify()

'event handler for multiple buffer mode

Dim i as Long

i = ADCardX1.GetADResult(ADBuf(0))

If i = ADCard_Success Then

Label1.Caption = "SeqNo=" + CStr(ADBuf(0))

Label2.Caption = "Chn" + CStr(iChn) + ":" + CStr(ADBuf((iSamp - 1) * NumChn + iChn + 1))

End If

End Sub

Private Sub Command1_Click()

Dim i as Long

If Working = 0 Then

'start command

ADCardX1.IOBase = &H110 ‘ 不同的 AD 板此参数不一样

ADCardX1.IRQNum = 5 ‘ 不同的 AD 板此参数不一样

ADCardX1.PhysAddr = &Hd8000 ‘ 不同的 AD 板此参数不一样

ADCardX1.DMAChn= 5 ‘ 不同的 AD 板此参数不一样

ADCardX1.NumInnerBuf = 1

If WorkMode = 0 Then

'multiple buffers mode

ADCardX1.NumInnerBuf = 2 'range: >=1

ADCardX1.SampPerChn = SampPerChn

Else

'single buffer mode

ADCardX1.NumInnerBuf = 1 'will be set to 1 internally

ADCardX1.SampPerChn = SampPerChn * 2

End If

ADCardX1.BegChn = 0

ADCardX1.NumChn = NumChn

ADCardX1.FrqSamp = 20000

ADCardX1.EnableNotify = True

If ADCardX1.Initial() = ADCard_Error Then

Label1.Caption = "Initial Error!"

Exit Sub

End If

If WorkMode = 0 Then

If ADCardX1.StartIntr() = ADCard_Error Then

Label1.Caption = "Start Interrupt Error!"

Exit Sub

End If

Else

If ADCardX1.StartSnapshot() = ADCard_Error Then

Label1.Caption = "Start Snapshot Error!"

Exit Sub

End If

Timer1.Interval = 20 '20 ms interval

Timer1.Enabled = True

End If

ReDim ADBuf(SampPerChn * NumChn + 1)

Working = 1

Command1.Caption = "Stop"

Else

'stop command

If WorkMode = 0 Then

i = ADCardX1.StopIntr()

Else

i = ADCardX1.StopSnapshot()

Timer1.Enabled = False

End If

Working = 0

Command1.Caption = "Start"

End If

End Sub

Private Sub Form_Load()

Working = 0

'set multiple/single buffers mode

WorkMode = 0 '1

End Sub

Private Sub Timer1_Timer()

'event handler for single buffer mode

Dim SampPtr as Long, i as Long

If Working = 0 Then Exit Sub

i = ADCardX1.GetSnapshot(ADBuf(0), SampPerChn, SampPtr)

If i = ADCard_Success Then

Label1.Caption = "SeqNo=" + CStr(ADBuf(0))

Label2.Caption = "Chn" + CStr(iChn) + ":" + CStr(ADBuf((iSamp - 1) * NumChn + iChn + 1))

End If

End Sub