1 前言
现代电子和计算机技术的发展为信息的转换与处理提供了极其完善的手段,使检测与控制技术发展到了新的阶段,数据采集卡的应用就是其中的一项重要内容。目前,Windows正以其良好的图形用户界面、灵活简单的操作赢得了广泛的用户。在工业控制系统的开发中,越来越多的用户也要求控制系统提供Windows风格的友好界面。C++Builder是Borland(Inprise)公司开发的Windows下可视化的C++编程环境,它常被简称为BCB或CB。BCB不仅功能强大,而且学习简单、使用方便,但它不具备直接对硬件I/O地址进行读写的能力,需要调用DLL函数实现对I/O端口的访问和控制,PCL
2 PCL
研华PCL
外部信号(数字量、模拟量) |
|
PCL |
|
计算机 |
图1 PCL
图2 实践应用原理图
3.1 DLL技术
对PCL
(1)利用“研华”光盘中附带的GeniDAQ Development开发环境,这是研华针对PCL系列板提供的标准开发环境,其优点是针对性强,缺点是不是通用的开发环境,程序移植性较差;
(2)由用户自行开发针对底层硬件的驱动程序,这种方法灵活性最大,代码执行效率也高,可以充分发挥硬件的性能,但是要求开发者具有相当高的计算机软、硬件水平;
(3)采用通用的开发环境(Visual C++、Delphi、C++Builder等),调用“研华”提供的标准动态链接库文件和第三方制作的ActiveX控件,采用这种方法可以在一定程度上降低程序开发的难度,在提供较好灵活性的同时,提供相对于第一种方法更好的移植性。因此,在实际中多采用第三种方法进行软件开发。
动态链接库(Dynamic Link Library,简称DLL)是一种基于Windows的程序模块。之所以称之为“动态”,是因为它们在运行期间被装入和链接到应用程序的,而不是在编译期间。DLL中只包含供应用程序运行时装入该DLL的有关信息,并非是源代码的复制,因此在Windows中使用DLL可以使多个应用程序之间共享代码和源程序,从而提高运行效率。下面对几个关键的DLL函数作简单说明。
(1)DRV_DeviceOpen( ):该函数必须最先被调用,它加载一个设备驱动程序到内存,并确定设备的类型,完成对设备的初始化,使设备做好I/O的准备工作,同时返回一个函数值,若设备驱动成功则返回非“0”的设备句柄,否则返回“0”。
(2)DRV_DeviceClose( ):该函数是关闭由DRV_DeviceOpen( )函数打开的设备,它的函数参数是由DRV_DeviceOpen( )函数返回的设备句柄,若设备关闭成功则返回非“0”,否则返回“0”。
(3)DRV_DeviceGetFeatures( ):该函数从由DRV_DeviceOpen( )函数打开的设备中获取相关的硬件信息;同时返回一个函数值,若操作成功则返回非“0”值,否则返回“0”。
(4)DRV_AIVoltageIn( ):外部模拟量信号首先在PCL
(5)DRV_AOVoltageOut( ):该函数的作用是输出模拟量值到PCL
(6)DRV_DioReadPortByte( )和DRV_DioWritePortByte( ):这两个函数的作用是帮助计算机与外部设备通过PCL
3.2 I/O基地址的设置
PCL
表1 PCL
3.3
为简明起见,笔者用一个实例阐述PCL
(1)按照用户手册,根据实际需要完成PCL
创建一个C++Builder工程,并根据实际需要进行窗体的设计,笔者设计的窗体外观如下:
数字量的输入共有16路(即16位数字量),分为两个字节,低八位记为通道0,高八位记为通道1,而“输入通道显示”可以清楚的指示出是哪一路是高电平或低电平,“扫描时间”用来更改数字量输入的刷新时间;数字量的输出同样分为通道0和通道1;模拟量最多有16路单通道信号输入,电压范围可由软件设定为±5V、±2.5V、±1.25V、±0.625V,在“输入数据”栏显示外部输入的电压值;模拟量的输出只有两个通道,在“手动输出”栏可以任意设定输出的电压值(不超过额定输出电压),“自动输出”是指把外部输入的电压值直接输出。
(2)在Unit1.h头文件中定义一些公有变量,代码如下:
PT_DioReadPortByte ptDioReadPortByte; //数字量输入数据结构体
PT_DioWritePortByte ptDioWritePortByte; //数字量输出数据结构体
PT_AIVoltageIn ptAIVoltageIn; //模拟量输入经A/D后的数据
PT_AIGetConfig ptAIGetConfig; //模拟量输入数据结构体
PT_AOVoltageOut ptAOVoltageOut; //模拟量输出数据结构体
(3)程序源代码的编制如下:
void __fastcall TForm1::Button1Click(TObject *Sender) //选择板卡
{… …
DRV_DeviceOpen(0, &hDH);
… … }
//数字量的输入和输出
void __fastcall TForm1::TimInTimer(TObject *Sender)
{ ptDioReadPortByte.port =ComboBox1->Text.ToInt() ;
… …
DRV_DioWritePortByte(hDH,(LPT_DioWritePortByte)&ptDioWritePortByte);
… … }
//模拟量输入
void __fastcall TForm1::TimAInTimer(TObject *Sender) //模拟量输入扫描循环
{ gwChannel=ComboBox3->Text .ToInt();
ptAIVoltageIn.TrigMode = 0; // 触发方式 软件/内部触发
… …}
//模拟量输出
void __fastcall TForm1::TimAOutTimer(TObject *Sender)
{ ptAOVoltageOut.chan = ComboBox5->Text .ToInt() ;
ptAOVoltageOut.OutputValue = fVoltage;
DRV_AOVoltageOut(hDH,(LPT_AOVoltageOut)&ptAOVoltageOut);}
//程序退出
void __fastcall TForm1::ExitClick(TObject *Sender)
{ … …
DRV_DeviceClose((LONG far *)&hDH);
Close(); }
说明:因限于篇幅,上述程序设计只列出部分关键代码。
4 结束语
本文充分利用台湾研华公司提供的动态链接库文件,结合C++Builder可视化的编程环境,在充分发挥PCL
参考文献:
[1]PCL
[2]郭文夷,等。C++ Builder 6.0 程序设计[M]。西安:西安电子科技大学出版社,2004。