logo资料库

研华采集卡驱动程序工作原理及流程说明.pdf

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
研华采集卡驱动程序工作原理及流程说明 (适用于 pci-1710 1711,1712 ,1713, 1714 ,1716 ,1718 ,pcl-818 ,pcl-816) 1 引言 研华公司是台湾和中国大陆工业电脑产品最大的供应厂商,其 PC&Web-based 数据采集和控制产品更是以优良的性价比获得了众多的客户的青 睐。32 位 DLL 驱动程序是研华为诸如 VC,VB,DELPHI,Borland C++,C++ Builder 等高级语言提供的接口,通过这个驱动程序,编程人员可以方便的对硬件进行编 程控制。该驱动程序覆盖了每一款研华的数据采集卡以及 MIC-2000、ADAM-4000 和 ADAM-5000 系列模块,应用极为广泛,是编制数据采集程序的基础。本文是在 实际编写动态数据采集程序中经验的积累,对利用 32 位驱动程序有实用价值。 2 32 位驱动程序概览 32 位驱动程序主要包括 10 类函数及其相应的数据结构,这些函数和数 据结构在 Adsapi 32.lib 中实现。这 10 类函数分别是: Device Functions 设备函数 Analog Input Function Group 模拟输入函数组 Analog Output Function Group 模拟输出函数组 Digital Input/Output Function Group 数字输入/输出函数组 Counter Function Group 计数器函数组 Temperature Measurement Function Group 温度测量函数组 Alarm Function Group 报警函数组 Port Function Group 端口函数组 Communication Function Group 通信函数组 Event Function Group 事件函数组 可以把这 10 类函数分为两个部分:设备函数部分(只包括第一类函数)和操 作函数部分(包括第一类函数外的所有函数),设备函数部分负责获取硬件特征和 开关硬件。而操作函数部分则在硬件设备就绪以后,进行具体的采集、通信、输 出、报警等工作。具体工作结束后,调用设备函数关闭设备。这些函数的调用过 程如图 1 所示。
3 动态数据采集程序的实现 用 32 位 DLL 驱动程序实现动态数据采集程序时,传输方式可以有中断传输, DMA 传输和软件传输三种方式可选。软件传输速度最慢,DMA 传输和中断传输方 式是最常用的触发方式。这里主要介绍中断传输方式,但 DMA 传输方式和中断方 式在使用 32 位 DLL 驱动程序实现时流程基本一样,可以参考。 在各种高级语言下,驱动程序提供的函数形式相同,所以此处只给出驱动程 序函数的调用流程,在具体的某种高级语言下,只要按照流程图就能实现动态数 据采集。中断传输流程图如下:
ADS_EVT_BUFCHANGE 事件,该事件表示内部缓冲区已经半满。可以将这部分数据 传输到用户缓冲区中。 DRV_FAIIntScanStart:开始中断触发方式的 A/D 转换。 DRV_CheckEvent:检查是否有设定的事件发生。 DRV_FAICheck:检查 A/D 转换的状态。在本例中用于检查究竟是内部缓冲区的前 半部分满了,还是后半部分满了。 DRV_FAITransfer:将采集的数据从内部缓冲区传输到用户缓冲区。 DRV_FAIStop:结束 A/D 转换。 DRV_DeviceClse:关闭指定的数据采集板。 4 动态采集程序涉及到驱动程序中部分概念的分析 4.1 使用的缓冲区 在驱动程序进行 A/D 或 D/A 转换时,有三个相关的概念需要分清楚:采集板 上的 FIFO,计算机内存中的内部缓冲区和用户缓冲区。 FIFO 为采集板卡上自带的使用 FIFO 缓冲区可以达到更高的采集频率,如 PCI-1710 使用 4K 的 FIFO 缓冲区后,最高采样频率可达到 100KHZ。但是有些型 号的采集板不带 FIFO 缓冲区。 内部缓冲区和用户缓冲区是数据采集程序动态分配给驱动程序使用的两块 内存区域。内部缓冲区主要由驱动程序使用,驱动程序从 板卡 FIFO 中或寄存器 将数据通过中断方式或 DMA 方式传输到内部缓冲区。在例程中该 BUFFER 指针一 般用 hBuf 命名. 如果是非循环采集,采样完设定好的数据个数后采集停止,驱动停止往内部缓冲 区存放数据。如果循环采集,内部缓冲区会循环使用,用户需要在 BUFFERCHANGE 事件用 DRV_FAITransfer 及时将数据取走,以免被新到的数据覆盖。可以放到用 户缓冲区中,或者进行存到硬盘的其他数据操作。 用户缓冲区是用户自己用来存放数据的地方,例程中开辟的大小和内部缓冲区一 致,这只是示例。 实际应用当中,用户可以根据需要开辟用户缓冲区的大小。 例如开辟一个较大的用户缓冲区,在循环采集中将每次采集的数据依次存放其 中。采集结束后统一处理。在例程中该 BUFFER 指针一般用 hUserBuf 命名, 这二者还有一个区别在于,内部缓冲区中存放的是 Raw Data(原始数据),用户 缓冲区中存放的可以是原始数据也可以是 Float data 电压值。通过 ptFAITransfer.DataType 参数来确定转换时是原始数据还是电压值。关于原始 数据和电压值的区别后面会有介绍。 中断触发方式的 A/D 转换中这三种缓冲区的使用如图 3 所示。
F I F O DRV_FAIIntStart DRV_FAIDmaExStart DRV_FAIDmaStart DRV_FAITransfer ptFAITransfer.Data Type=0 raw data 1 float data 用 户 缓 冲 区 内 部 缓 冲 区 在使用 DRV_FAIIntScanStart 函数将采样值放到内部缓冲区有两种方式:有 FIFO 和无 FIFO。没有 FIFO 时,每完成一次 A/D 转换就产生一个中断,驱动程序 响应中断将这个采样值传到内部缓冲区中。有 FIFO 时,采样值先放在 FIFO 中, 当 FIFO 半满或全满时,才产生一个中断,驱动程序响应中断将 FIFO 中的数据传 送到内部缓冲区中,这是使用 FIFO 能提高采样频率的原因。 4.2 内部缓冲区的使用方式。 驱动程序在操作内部缓冲区时是将内部缓冲区分为上下两半缓冲区来 分别操作。通过这样来保证高速连续采集时,数据不会丢失。在采集时驱动程序 从板卡 FIFO 或寄存器中将数据传输到内部缓冲区中,当内部缓冲区半满时驱动 程序发出 BufferChange 事件。用户通过执行 DRV_FAICheck 函数返回的 HalfReady 来判断是上半部分还是下半部分缓冲满了,然后执行 DRV_FAITransfer 来将相应的缓冲中的数据搬走。 在不了解数据采集的 DMA 触发方式时,很容易把中断触发方式下,调用 DRV_FAIIntScanStart 函数时同时使用 FIFO 和内部缓冲区的方式认为是双缓冲 区工作方式,进而对 PTFAICheck 结构的 ActiveBuf 域产生误解。实际上,双缓 冲区是指同时使用 A、B 两个内部缓冲区。这是 PCL-1800 卡在 DMA 触发方式下的 特殊工作方式,由 DRV_FAIDualDmaStart 函数启动。只有 PCL-1800 卡支持双缓 冲方式。在中断触发方式下不能同时使用双缓冲区的工作方式。所以我们一般使 用时 PT_FAITransfer. ActiveBuf=0 即单缓冲模式。 4.3 循环(cycle0 和非循环(no_cycle)
循环和非循环是指内部缓冲区的使用方式。 非循环方式下,内部缓冲区作为一个整体使用。在非循环方式下执行一次 DRV_FAIIntScanStart/DRV_FAIIntStart 函数只能进行有限次(次数就是通过参 数 count 设定的采样个数)的 A/D 转换,DRV_FAIIntScanStart 函数执行过程中 将所有数据都放到内部缓冲区;A/D 转换结束后,在 ADS_EVT_TERMINATED 事件 的处理函数中再用 DRV_FAITransfer 函数将数据传送到用户缓冲区中。 循环方式下,内部缓冲区分为两个半区使用。执行一次 DRV_FAIIntScanStart/DRV_FAIIntStart 函数可以进行无限次的 A/D 转换,直到 调用 DRV_FAI_Stop 函数。这种方式下有限的内部缓冲区不可能容纳无限多的采 集数据。因此,将内部缓冲区分成前后对等的两个半区。当前半区填满后产生一 个 ADS_EVT_BUFCHANGE 事件,采集程序中的事件检查循环捕获这个事件,调用 DRV_FAI_Transfer 函数把数据传送到用户缓冲区;与此同时 DRV_FAIIntScanStart/DRV_FAIIntStart 函数将新转换的数据放到内部缓冲区 的后半部分。当后半区填满后再产生一个 ADS_EVT_BUFCHANGE 事件,并用 DRV_FAIIntScanStart/DRV_FAIIntStart 函数将新转换的数据放到数据传输完 毕的前半缓冲区,如此循环。 4.4 Raw Data(原始数据)和 voltage(电压值) 以 PCL818 为例,它的转换芯片是 12 位的,所以它可以把采集的电压量程分 为 4096 段,这种方式称为量化,而 Raw Data 就是将被采集量量化后的整数值。 驱动程序将量化值用 3 位十六进制数表示,所以 Raw Data 的示数范围就是 000-fff,在内部缓冲区中的数值就是这种量化的原始数据。用户缓冲区中存放 Voltage(电压值),将 Raw Data 转化为电压值由 CRVFAITransfer 函数完成,当 PTFAITransfer 的 DataType=0 时,不进行 Raw Data 到电压值的转化,这时候在 用户缓冲区中得到的就是量化的 12 位十六进制整数值。 5 动态采集程序涉及到驱动程序中一些参数的分析 5.1 PTFAICheck 结构的 HalfReady 域 该域说明哪半个缓冲区已满。在使用 FIFO 缓冲区的情况下,FIFO 缓冲区和 内部数据缓冲区都有半满(halffull)的情况。容易混淆此处的 HalfReady 是指 FIFO 缓冲区中的半区还是内部数据缓冲区的半区。事实上,DRVFAICheck 都是返 回的内部缓冲区的状态,不反映 FIFO 缓冲区状态;所以此处是指的内部数据缓 冲区的半区。 5.2 ADSEVTBUFCHANGE 事件的触发时机 在内部数据缓冲区的上下两个半缓冲区间切换时。 5.3 增益列表起始地址 在编写数据采集程序时,都要考虑多通道同时采集,而且都要考虑开始通道 的任意性,所以通常的做法是为增益列表开辟一块增益列表存储区,从 0 开始每
个存储单元对应一个通道的增益值,但是要注意,在起始通道不为零时不能将这 个存储区的起始地址直接赋给驱动函数的“增益列表起始地址”参数,如 PTFAIIntScanStart 结构的 GainList 域;因为驱动程序是直接从“增益列表起 始地址”参数表示的起始地址去提取起始通道的增益值,而不会根据“起始通道” 参数在增益列表中选取对应的增益值。 5.4 CheckEvent 的检查周期 CheckEvent 函数是在一个周期中检查是否事件发生,如果有就立即返 回事件的类型,如果没有就返回一个“check event error!”错误。CheckEvent 函数与 DRV_FAICheck 函数不同,程序需要不的调用 DRV_FAICheck 函数来检查硬 件工作的最新情况。程序调用 DRV_FAICheck 函数要占用计算机 CPU 时间,但是 使用 CheckEvent,只需要占用 CPU 调用一次 CheckEvent 函数的时间,就可以监 视一个监视周期内的事件发生情况。在这个周期内没有事件发生就不占用 CPU 时间,CheckEvent 函数采用同步方式检查事件的发生。PTCheckEvent 结构的 Milliseconds 域说明了 CheckEvent 函数的检查周期。应为执行 CheckEvent 函 数后这个线程实际是被挂起了,执导有事件产生才唤醒,执行。 6 结束语 本文着重分析了在使用研华 32 位 dll 驱动程序编写动态数据采集程序时所 碰到的概念及参数。通过本文读者可能加深对 32 位 dll 驱动程序的认识,从而 达到更加自由,灵活使用 32 位 dll 驱动程序的目的。
分享到:
收藏