严格意义上讲,此文不算OPC的范畴。起因是,另一个项目的PLC强人说,OPC慢,用prodave吧,好,用就用吧,装好Prodave看是看其英文资料,虽然英文不好,但好在这里英文
很简单。好了,上网查了点资料,这里还要感谢几个朋友的帮忙,让我对于C#与C++的数据结构有了更进一步的认识,也学会了使用DllImport
在本文的开头,我要说明下,Prodave是西门子的通信方式,即使我提供了Prodave6.dll,您不注册也是没用用的,所以请使用西门子的安装程序,哪里下载?自己百度一下。不
要来问我哪里下载Prodave6.dll,也不要问我为什么程序会报错说没有注册dll
下面开始进入正文。
(1)上来第一个函数,就是连接PLC的LoadConnection_ex6,在说明书里描述如下:
LoadConnection_ex6
The basic LoadConnection_ex6 function initializes the adapter, checks if the
driver is loaded, initializes the addresses that have been assigned parameters and
activates the selected interface.
LoadConnection_ex6 is used to set up a transport connection via MPI/PB- or IP
addresses (TCP/IP protocol)
int LoadConnection_ex6 (int ConNr, char* pAccessPoint, int ConTableLen,
CON_TABLE_TYPE * pConTable);
Parameters
ConNr
[in] Number of the connection (max. 64 connections).
pAccessPoint
[in] access point (zero-terminated) of the driver used, e.g. "S7ONLINE" for the MPI
driver or 0 (default).
ConTableLen
[in] length of the table of connections provided by the user in bytes
pConTable
[in] pointer to address list of connected users; ‘Adr ==0’ is taken as the end mark of
the list.
#pragma pack(1)
typedef union {
unsigned char Mpi; // MPI/PB station address (2)
unsigned char Ip[4]; // IP address (192.168.0.1)
unsigned char Mac[6]; // MAC address (08-00-06-01-AA-BB)
} CON_ADR_TYPE;
typedef struct {
CON_ADR_TYPE Adr; // connection address
unsigned char AdrType; // Type of address: MPI/PB (1), IP (2), MAC (3)
unsigned char SlotNr; // Slot number
unsigned char RackNr; // Rack number
} CON_TABLE_TYPE;
#pragma pack(1)
好吧,起先其他的转换网上都有,不难,但是出现了union共用体,恩C#没有这个概念。怎么办?起先,参考网上的资料,采用
[StructLayout(LayoutKind.Explicit)]
struct
S1
{
[FieldOffset(
0
)]
int
a;
[FieldOffset(
0
)]
int
b;
}
最后我联想到在内存中实际上这个共用体用的是一个以最大字段为空间大小的内存,于是乎尝试了,直接定义[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]byte
Mac[6],果然解决了,共用体的问题,其实C++传进去的参数也其实是6字节的数组而已,进而想既然一个数组搞定,那么还用共用体干嘛,不要了,于是出现了如下函数转换的正
解:
Code
public struct CON_TABLE_TYPE//待连接plc地址属性表
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
//public CON_ADR_TYPE Adr; // connection address
public byte[] Adr; // connection address
// MPI/PB station address (2)
// IP address (192.168.0.1)
// MAC address (08-00-06-01-AA-BB)
public byte AdrType; // Type of address: MPI/PB (1), IP (2), MAC (3)
public byte SlotNr; // Slot number
public byte RackNr; // Rack number
}
[DllImport("Prodave6.dll")]//连接PLC操作
//参数:连接号(0-63)、常值"S7ONLINE"、待连接plc地址属性表长度(字节为单位,常值9)、待连接plc地址属性表
public extern static int LoadConnection_ex6(int ConNr, string pAccessPoint, int ConTableLen, ref CON_TABLE_TYPE pConTable);
(2)关于unsigned char * pBuffer,这个unsigned char *其实有2个转换可选,有时可以使用byte[],有时则是StringBuilder,这就要集体问题具体分析了。例如:
int
GetErrorMessage_ex6 (
int
ErrorNr, unsigned
long
BufLen, unsigned
char
*
pBuffer);
void
copy_buffer_ex6 (unsigned
char
*
pTargetBuffer, unsigned
char
*
pSourceBuffer, unsigned
long
Amount);
前者就转换成StringBuilder后者是byte[]。
(3)有些变量虽是整型但是可以用枚举,而且用枚举感觉更合适
例如int db_read_ex6 (unsigned short BlkNr, unsigned char DatType, unsigned
short StartNr, unsigned long * pAmount, unsigned long BufLen, unsigned
char * pReadBuffer, unsigned long * pDatLen)中,unsigned char DatType其实指的是“0x02 = BYTE, 0x04 = WORD, 0x06 = DWORD default: DatType = 0x02”等数据类型
,因此可以翻译成
public
enum
DatType :
byte
//
PLC数据类型
{
BYTE
=
0x02
,
WORD
=
0x04
,
DWORD
=
0x06
,
}
(4)对了,如果是对象型的引用,比如unsigned char*转成byte[],是不需要加ref,但如果是c++ int转 c# int 则要加ref关键字。
要说明的就是这些,下面请各位看官看看我的转换代码吧,还请见教:
Code
public class Prodave6
{
#region 常值定义(用于极限值)
public const int MAX_CONNECTIONS = 64; // 64 is default in PRODAVE
public const int MAX_DEVNAME_LEN = 128;// e.g. "S7ONLINE"
public const int MAX_BUFFERS = 64; // 64 for blk_read() and blk_write()
public const int MAX_BUFFER = 65536; // Transfer buffer for error text)
#endregion
#region 结构体定义
public struct CON_TABLE_TYPE//待连接plc地址属性表
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
//public CON_ADR_TYPE Adr; // connection address
public byte[] Adr; // connection address
// MPI/PB station address (2)
// IP address (192.168.0.1)
// MAC address (08-00-06-01-AA-BB)
public byte AdrType; // Type of address: MPI/PB (1), IP (2), MAC (3)
public byte SlotNr; // Slot number
public byte RackNr; // Rack number
}
public enum DatType : byte//PLC数据类型
{
BYTE = 0x02,
WORD = 0x04,
DWORD = 0x06,
}
public enum FieldType : byte//PLC区域类型
{
//Value types as ASCII characters区域类型对应的ASCII字符
//data byte (d/D)
d = 100,
D = 68,
//input byte (e/E)
e = 101,
E = 69,
//output byte (a/A)
a = 97,
A = 65,
//memory byte (m/M)
m = 109,
M = 77,
//timer word (t/T),
t = 116,
T = 84,
}
#endregion
#region PLC基本函数
[DllImport("Prodave6.dll")]//连接PLC操作
//参数:连接号(0-63)、常值"S7ONLINE"、待连接plc地址属性表长度(字节为单位,常值9)、待连接plc地址属性表
public extern static int LoadConnection_ex6(int ConNr, string pAccessPoint, int ConTableLen, ref CON_TABLE_TYPE pConTable);
[DllImport("Prodave6.dll")]//断开PLC操作
//参数:连接号(0-63)
public extern static int UnloadConnection_ex6(UInt16 ConNr);
[DllImport("Prodave6.dll")]//激活PLC连接操作
//参数:连接号(0-63)
public extern static int SetActiveConnection_ex6(UInt16 ConNr);
[DllImport("Prodave6.dll")]//PLC db区读取操作
//参数:data block号、要读取的数据类型、起始地址号、需要读取类型的数量、缓冲区长度(字节为单位)、缓冲区、缓冲区数据交互的长度
public extern static int db_read_ex6(UInt16 BlkNr, DatType DType, UInt16 StartNr, ref UInt32 pAmount, UInt32 BufLen,
byte[] pBuffer, ref UInt32 pDatLen);
[DllImport("Prodave6.dll")]//PLC db区写入操作
//参数:data block号、要写入的数据类型、起始地址号、需要写入类型的数量、缓冲区长度(字节为单位)、缓冲区
public extern static int db_write_ex6(UInt16 BlkNr, DatType Type, UInt16 StartNr, ref UInt32 pAmount, UInt32 BufLen,
byte[] pBuffer);
[DllImport("Prodave6.dll")]//PLC 任意区读取操作
//参数:要读取的区类型、data block号(DB区特有,默认为0)、起始地址号、需要读取类型的数量、
//缓冲区长度(字节为单位)、缓冲区、缓冲区数据交互的长度
public extern static int field_read_ex6(FieldType FType, UInt16 BlkNr, UInt16 StartNr, UInt32 pAmount, UInt32 BufLen,
byte[] pBuffer, ref UInt32 pDatLen);
[DllImport("Prodave6.dll")]//PLC 任意区写入操作
//参数:要写入的区类型、data block号(DB区特有,默认为0)、起始地址号、需要写入类型的数量、
//缓冲区长度(字节为单位)、缓冲区
public extern static int field_write_ex6(FieldType FType, UInt16 BlkNr, UInt16 StartNr, UInt32 pAmount, UInt32 BufLen,
byte[] pBuffer);
[DllImport("Prodave6.dll")]//PLC M区某字节的某位读取操作
//参数:M区字节号、位号、当前的值(0/1)
public extern static int mb_bittest_ex6(UInt16 MbNr, UInt16 BitNr, ref int pValue);
[DllImport("Prodave6.dll")]//PLC M区某字节的某位写入操作
//参数:M区字节号、位号、要写入的值(0/1)
public extern static int mb_setbit_ex6(UInt16 MbNr, UInt16 BitNr, byte Value);
#endregion
#region PLC200用数据传输函数
[DllImport("Prodave6.dll")]//200系列PLC 任意区读取操作
//参数:要读取的区类型、data block号(DB区特有,默认为0)、起始地址号、需要读取类型的数量、
//缓冲区长度(字节为单位)、缓冲区、缓冲区数据交互的长度
public extern static int as200_field_read_ex6(FieldType FType, UInt16 BlkNr, UInt16 StartNr, UInt32 pAmount, UInt32 BufLen,
byte[] pBuffer, ref UInt32 pDatLen);
[DllImport("Prodave6.dll")]//200系列PLC 任意区写入操作
//参数:要写入的区类型、data block号(DB区特有,默认为0)、起始地址号、需要写入类型的数量、
//缓冲区长度(字节为单位)、缓冲区
public extern static int as200_field_write_ex6(FieldType FType, UInt16 BlkNr, UInt16 StartNr, UInt32 pAmount, UInt32 BufLen,
byte[] pBuffer);
[DllImport("Prodave6.dll")]//200系列PLC M区某字节的某位读取操作
//参数:M区字节号、位号、当前的值(0/1)
public extern static int as200_mb_bittest_ex6(UInt16 MbNr, UInt16 BitNr, ref int pValue);
[DllImport("Prodave6.dll")]//200系列PLC M区某字节的某位写入操作
//参数:M区字节号、位号、要写入的值(0/1)
public extern static int as200_mb_setbit_ex6(UInt16 MbNr, UInt16 BitNr, byte Value);
#endregion
#region PLC数据转换函数
[DllImport("Prodave6.dll")]//诊断错误信息操作
//参数:错误代号、缓冲区大小(字节为单位)、缓冲区
public extern static int GetErrorMessage_ex6(int ErrorNr, UInt32 BufLen, [MarshalAs(UnmanagedType.LPStr)] StringBuilder pBuffer);
[DllImport("Prodave6.dll")]//S7浮点数转换成PC浮点数
//参数:S7浮点数、PC浮点数
public extern static int gp_2_float_ex6(UInt32 gp, ref float pieee);
[DllImport("Prodave6.dll")]//PC浮点数转换成S7浮点数
//参数:PC浮点数、S7浮点数
public extern static int float_2_gp_ex6(float ieee, ref UInt32 pgp);
[DllImport("Prodave6.dll")]//检测某字节的某位的值是0或1
//参数:字节值、位号
public extern static int testbit_ex6(byte Value, int BitNr);
[DllImport("Prodave6.dll")]//检测某字节的byte值转换成int数组
//参数:byte值、int数组(长度为8)
public extern static void byte_2_bool_ex6(byte Value, int[] pBuffer);
[DllImport("Prodave6.dll")]//检测某字节的int数组转换成byte值
//参数:int数组(长度为8)
public extern static byte bool_2_byte_ex6(int[] pBuffer);
[DllImport("Prodave6.dll")]//交换数据的高低字节——16位数据
//参数:待交换的数据
public extern static UInt16 kf_2_integer_ex6(UInt16 wValue);//16位数据——WORD
[DllImport("Prodave6.dll")]//交换数据的高低字节——32位数据
//参数:待交换的数据
public extern static UInt32 kf_2_long_ex6(UInt32 dwValue);//32位数据——DWORD
[DllImport("Prodave6.dll")]//交换数据缓冲区的的高低字节区,例如pBuffer[0]与pBuffer[1],pBuffer[2]与pBuffer[3]交换
//参数:待交换的数据缓冲区,要交换的字节数,如Amount=pBuffer.Length,则交换全部缓冲
public extern static void swab_buffer_ex6(byte[] pBuffer, UInt32 Amount);
[DllImport("Prodave6.dll")]//复制数据缓冲区
//参数:目的数据缓冲区,源数据缓冲区,要复制的数量(字节为单位)
public extern static void copy_buffer_ex6(byte[] pTargetBuffer, byte[] pSourceBuffer, UInt32 Amount);
[DllImport("Prodave6.dll")]//把二进制数组传换成BCD码的数组——16位数据
//参数:要处理的数组,要处理的字节数,转换前是否先交换高低字节,转换后是否要交换高低字节
//InBytechange为1则转换BCD码之前,先交换高低字节
//OutBytechange为1则转换BCD码之后,再交换高低字节
//如果InBytechange和OutBytechange都没有置1,则不发生高低位的交换
//16位数据BCD码值的许可范围是:+999 —— -999
public extern static void ushort_2_bcd_ex6(UInt16[] pwValues, UInt32 Amount, int InBytechange, int OutBytechange);//16位数据——WORD
[DllImport("Prodave6.dll")]//把二进制数组传换成BCD码的数组——32位数据
//参数:要处理的数组,要处理的字节数,转换前是否先交换高低字节,转换后是否要交换高低字节
//InBytechange为1则转换BCD码之前,先交换高低字节
//OutBytechange为1则转换BCD码之后,再交换高低字节
//如果InBytechange和OutBytechange都没有置1,则不发生高低位的交换
//32位数据BCD码值的许可范围是:+9 999 999 —— -9 999 999
public extern static void ulong_2_bcd_ex6(UInt32[] pdwValues, UInt32 Amount, int InBytechange, int OutBytechange);//32位数据——DWORD
[DllImport("Prodave6.dll")]//把BCD码的数组传换成二进制数组——16位数据
//参数:要处理的数组,要处理的字节数,转换前是否先交换高低字节,转换后是否要交换高低字节
//InBytechange为1则转换BCD码之前,先交换高低字节
//OutBytechange为1则转换BCD码之后,再交换高低字节
//如果InBytechange和OutBytechange都没有置1,则不发生高低位的交换
//16位数据BCD码值的许可范围是:+999 —— -999
public extern static void bcd_2_ushort_ex6(UInt16[] pwValues, UInt32 Amount, int InBytechange, int OutBytechange);//16位数据——WORD
[DllImport("Prodave6.dll")]//把BCD码的数组传换成二进制数组——32位数据
//参数:要处理的数组,要处理的字节数,转换前是否先交换高低字节,转换后是否要交换高低字节
//InBytechange为1则转换BCD码之前,先交换高低字节
//OutBytechange为1则转换BCD码之后,再交换高低字节
//如果InBytechange和OutBytechange都没有置1,则不发生高低位的交换
//32位数据BCD码值的许可范围是:+9 999 999 —— -9 999 999
public extern static void bcd_2_ulong_ex6(UInt32[] pdwValues, UInt32 Amount, int InBytechange, int OutBytechange);//32位数据——DWORD
[DllImport("Prodave6.dll")]//查看64个连接中哪些被占用,哪些已经建立
//参数:传输缓冲的字节长度,64位长度的数组(0或1)
public extern static void GetLoadedConnections_ex6(UInt32 BufLen, int[] pBuffer);
#endregion
#region 自定义辅助函数
public static UInt16 bytes_2_word(byte dbb0, byte dbb1)//将高低2个byte转换成1个word
{
UInt16 dbw0;
dbw0 = (UInt16)(dbb0 * 256 + dbb1);
return dbw0;
}
public static UInt32 bytes_2_dword(byte dbb0, byte dbb1, byte dbb2, byte dbb3)//将高低4个byte转换成1个dword
{
UInt32 dbd0;
dbd0 = (UInt32)(dbb0 *16777216 + dbb1 * 65536 + dbb2 * 256 + dbb3);
return dbd0;
}
public static UInt32 words_2_dword(UInt16 dbw0, UInt16 dbw2)//将高低2个word转换成1个dword
{
UInt32 dbd0;
dbd0 = (UInt32)(dbw0 * 65536 + dbw2);
return dbd0;
}
public static byte[] word_2_bytes(UInt16 dbw0)//将word拆分为2个byte
{
byte[] bytes = new byte[2];
bytes[0] = (byte)(dbw0 / 256);
bytes[1] = (byte)(dbw0 % 256);
return bytes;
}
public static byte[] dword_2_bytes(UInt32 dbd0)//将dword拆分为4个byte
{
byte[] bytes = new byte[4];
bytes[0] = (byte)(dbd0 / 16777216);
dbd0 = dbd0 % 16777216;
bytes[1] = (byte)(dbd0 / 65536);
dbd0 = dbd0 % 65536;
bytes[2] = (byte)(dbd0 / 256);
bytes[3] = (byte)(dbd0 % 256);
return bytes;
}
public static UInt16[] dword_2_words(UInt32 dbd0)//将dword拆分为2个word
{
UInt16[] words = new UInt16[2];
words[0] = (UInt16)(dbd0 / 65536);
words[1] = (UInt16)(dbd0 % 65536);
return words;
}
#endregion
}
(5)以下是测试的代码:
//以下测试LoadConnection_ex6
short ConNr= 63; // First connection;(0 63);(max. 64 connections).
string AccessPoint = "S7ONLINE"; // Default access point——S7ONLINE
Prodave6_CS.Prodave6.CON_TABLE_TYPE ConTable ;// Connection table
int ConTableLen = System.Runtime.InteropServices.Marshal.SizeOf(typeof(Prodave6_CS.Prodave6.CON_TABLE_TYPE)) ;// Length of the connection table
int RetValue;
ConTable.Adr=new byte[]{192,168,1,200,0,0};
ConTable.AdrType = 2; // Type of address: MPI/PB (1), IP (2), MAC (3)
ConTable.SlotNr = 2; // 插槽号
ConTable.RackNr = 0; // 机架号
RetValue = Prodave6.LoadConnection_ex6(ConNr, AccessPoint, ConTableLen,ref ConTable);
//以下测试SetActiveConnection_ex6
UInt16 UConNr = (UInt16)ConNr;
RetValue = Prodave6.SetActiveConnection_ex6(UConNr);
//以下测试db_write_ex6
UInt16 BlkNr = 4;//data block号
Prodave6.DatType DType = Prodave6.DatType.BYTE;//要读取的数据类型
UInt16 StartNr = 0;//起始地址号
UInt32 pAmount = 20;//需要读取类型的数量
UInt32 BufLen = 20;//缓冲区长度(字节为单位)
//参数:data block号、要写入的数据类型、起始地址号、需要写入类型的数量、缓冲区长度(字节为单位)、缓冲区
byte[] pWriteBuffer = new byte[20];
for (int i = 0; i < pWriteBuffer.Length; i++)
pWriteBuffer[i] = (byte)(i+1);
RetValue = Prodave6.db_write_ex6(BlkNr, DType, StartNr, ref pAmount, BufLen, pWriteBuffer);
//以下测试db_read_ex6
//参数:data block号、要读取的数据类型、起始地址号、需要读取类型的数量、缓冲区长度(字节为单位)、
//缓冲区、缓冲区数据交互的长度
byte[] pReadBuffer = new byte[20];
UInt32 pDatLen = 0;
RetValue = Prodave6.db_read_ex6(BlkNr, DType, StartNr, ref pAmount, BufLen, pReadBuffer, ref pDatLen);
//以下测试field_read_ex6(测试DB区)
//参数:data block号、要读取的数据类型、起始地址号、需要读取类型的数量、缓冲区长度(字节为单位)、
//缓冲区、缓冲区数据交互的长度
Prodave6.FieldType FType = Prodave6.FieldType.D;
for (int i = 0; i < pWriteBuffer.Length; i++)
pWriteBuffer[i] = (byte)(i);
RetValue = Prodave6.field_write_ex6(FType, BlkNr, StartNr, pAmount, BufLen, pWriteBuffer);
//以下测试field_read_ex6(测试DB区)
//参数:data block号、要读取的数据类型、起始地址号、需要读取类型的数量、缓冲区长度(字节为单位)、
//缓冲区、缓冲区数据交互的长度
byte[] pReadBuffer2 = new byte[20];
RetValue = Prodave6.field_read_ex6(FType, BlkNr, StartNr, pAmount, BufLen,pReadBuffer2, ref pDatLen);
//以下测试field_read_ex6(测试M区)
//参数:data block号、要读取的数据类型、起始地址号、需要读取类型的数量、缓冲区长度(字节为单位)、
//缓冲区、缓冲区数据交互的长度
Prodave6.FieldType FTypeM = Prodave6.FieldType.M;
byte []pWriteBufferM = {2};
RetValue = Prodave6.field_write_ex6(FTypeM, 0, 100, 1, 1, pWriteBufferM);
//以下测试field_read_ex6(测试M区)
//参数:data block号、要读取的数据类型、起始地址号、需要读取类型的数量、缓冲区长度(字节为单位)、
//缓冲区、缓冲区数据交互的长度
byte[] pReadBufferM2 = new byte[1];
RetValue = Prodave6.field_read_ex6(FTypeM, 0, 100, 1, 1, pReadBufferM2, ref pDatLen);
//以下测试mb_setbit_ex6
UInt16 MbNr = 100;//mb block号
UInt16 BitNr = 0;//位号
byte Value = 1;//0、1
RetValue = Prodave6.mb_setbit_ex6(MbNr,BitNr, Value);
//以下测试mb_bittset_ex6(测试DB区)
int pValue = 0;
RetValue = Prodave6.mb_bittest_ex6(MbNr, BitNr, ref pValue);
//以下测试GetLoadedConnections_ex6
BufLen = 64;
int[] pBufferI = new int[64];
Prodave6.GetLoadedConnections_ex6(BufLen, pBufferI);
//以下测试UnloadConnection_ex6
RetValue = Prodave6.UnloadConnection_ex6(UConNr);
//以下测试GetErrorMessage_ex6
int ErrorNr = 0x7040; // Block boundary exceeded, correct the number
StringBuilder Buffer = new StringBuilder(300); // Transfer buffer for error text
BufLen = (UInt32)Buffer.Capacity; // Buffer length
RetValue = Prodave6.GetErrorMessage_ex6(ErrorNr, BufLen, Buffer);
//以下测试float_2_gp_ex6
float ieee = 1.2F;
UInt32 gp=0;
float pieee=0;
RetValue = Prodave6.float_2_gp_ex6(ieee, ref gp);
RetValue = Prodave6.gp_2_float_ex6(gp,ref pieee);
//以下测试gp_2_float_ex6
RetValue = Prodave6.testbit_ex6(7, 0);
RetValue = Prodave6.testbit_ex6(7, 1);
RetValue = Prodave6.testbit_ex6(7, 2);
RetValue = Prodave6.testbit_ex6(7, 3);
RetValue = Prodave6.testbit_ex6(7, 4);
RetValue = Prodave6.testbit_ex6(7, 5);
RetValue = Prodave6.testbit_ex6(7, 6);
RetValue = Prodave6.testbit_ex6(7, 7);
//以下测试byte_2_bool_ex6
int [] boolValue=new int[8];
Prodave6.byte_2_bool_ex6(255, boolValue);
//以下测试bool_2_byte_ex6
byte byteValue;
byteValue=Prodave6.bool_2_byte_ex6(boolValue);
//以下测试kf_2_integer_ex6和kf_2_long_ex6
UInt16 u16=25600;UInt16 u16_;
u16_=Prodave6.kf_2_integer_ex6(u16);
UInt32 u32 = 1677721600; UInt32 u32_;
u32_=Prodave6.kf_2_long_ex6(u32);
//以下测试swab_buffer_ex6(byte[] pBuffer, UInt32 Amount)
byte[] pBuffer=new byte[11];
UInt32 Amount=(UInt32)pBuffer.Length;
for (int i = 0; i < Amount; i++)
pBuffer[i] = (byte)(i+1);
Prodave6.swab_buffer_ex6(pBuffer, 6);
//以下测试copy_buffer_ex6
byte[] pSourceBuffer={1,2,3,4,5,6,7,8,9,10};
byte[] pTargetBuffer=new byte[10];
Prodave6.copy_buffer_ex6( pTargetBuffer, pSourceBuffer,8);
//以下测试ushort_2_bcd_ex6
UInt16[] pwValues = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
Prodave6.ushort_2_bcd_ex6(pwValues, 10, 0, 0);
//以下测试bcd_2_ushort_ex6
Prodave6.bcd_2_ushort_ex6(pwValues, 10, 0, 0);
UInt32[] pdwValues = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
//以下测试ulong_2_bcd_ex6
Prodave6.ulong_2_bcd_ex6(pdwValues,8, 0, 0);
//以下测试bcd_2_ulong_ex6
Prodave6.bcd_2_ulong_ex6(pdwValues, 8, 0, 0);
(6)最后,要说的是我没有转换全部的函数,只是挑了我认为比较常用的,或者我可能用的到的进行了转换。
详细的程序包,如果能要的话,可以去这里下载,同时还附带了英文版的prodave的pdf说明书哦:
http://download.csdn.net/source/1408924
如果只是要单独下载电子书的话,请看这里:
http://download.csdn.net/source/1408940
注意:开发环境为VS2008SP1,而其是控制台程序,没有输出,想看时如何测试各个函数的,请自行断点跟踪,程序是我测试过的,不存在错误,除非您该我代码。当然,您得在PLC的地址中开放必要的地址以供测试。