发表于:2006-04-21 19:30:00
1楼
力控的开发包里就有免费的Modbus协议(C语言的)
你可以参考:
long MakeWriteASCII16(CItem* pItem, LPCSTR szWriteData, char* chCommand, int& nCmdLen)
{
CPacket* pPacket = pItem->GetPacket();
(pPacket->GetPrivateData()).n[2] = HLS_W_WRITE;
CString csPmessage;
IOITEMDEF * pItemStru = pItem->GetItemStru();
chCommand[0] = 0x3A; //写入帧头
CDevice* pDevice = pPacket->GetDevice();
CString csAddr = pDevice->GetAddr();
char byBuf[256];
int nTemp;
long lData;
sscanf((const char *)csAddr,"%d",&nTemp);
sprintf(byBuf,"%02x",nTemp); //把十进制地址转化为十六进制字符串
chCommand[1] = byBuf[0]; //写入从机地址
chCommand[2] = byBuf[1];
switch(pItemStru->n[0]) //写入功能号
{
case 1: chCommand[3] = 0x30;//写输出线圈
chCommand[4] = 0x35;
csPmessage+="写输出线圈";
break;
case 2: chCommand[3] = 0x30;//写保持寄存器
chCommand[4] = 0x36;
csPmessage+="写保持寄存器";
break;
//hll modify
case 4: chCommand[3] = 0x30;//查询命令
chCommand[4] = 0x38;
csPmessage+="写保持寄存器";
break;
default :
break;
}
csPmessage+=":地址";
sprintf(byBuf,"%04x",pItemStru->n[1]);
chCommand[5] = byBuf[0]; //写入开始地址
chCommand[6] = byBuf[1];
chCommand[7] = byBuf[2];
chCommand[8] = byBuf[3];
csPmessage+=byBuf;
sscanf(szWriteData,"%ld",&lData);
switch(pItemStru->n[0])
{
case 1: if(lData!=0)
{
chCommand[9] = 0x46;
chCommand[10] = 0x46;
chCommand[11] = 0x30;
chCommand[12] = 0x30;
csPmessage += " ON";
}
else
{
chCommand[9] = 0x30;
chCommand[10] = 0x30;
chCommand[11] = 0x30;
chCommand[12] = 0x30;
csPmessage += " OFF";
}
break;
case 2: sprintf(byBuf,"%04x",WORD(lData));
chCommand[9] = byBuf[0];
chCommand[10] = byBuf[1];
chCommand[11] = byBuf[2];
chCommand[12] = byBuf[3];
csPmessage += byBuf;
csPmessage += "H";
break;
default:
break;
}
if((pDevice->GetCfgStru())->n[DEV_Model] == 0
&& pDevice->GetCfgStru()->n[DEV_Protocol] == 0)
{
BYTE bCheck = (BYTE)GetCheckCode(HLS_ASCII,chCommand,12);
sprintf(byBuf,"%02x",bCheck);
chCommand[13] = byBuf[0]; //写入校验码
chCommand[14] = byBuf[1];
chCommand[15] = 0x0D; //写入帧尾
chCommand[16] = 0x0A;
nCmdLen = 17;
chCommand[17] = '\0';
strupr(chCommand); //小写字母变为大写
}
else
{//只是为了转化成其他格式的命令,在这里不用生成校验
chCommand[13] = '\0';
strupr(chCommand);
nCmdLen = 13;
}
pDevice->ShowProcessMessage(csPmessage);
return SEND | WAIT;
}
//写16号命令
long MakeWriteASCII32To16(CItem* pItem, LPCSTR szWriteData, char* chCommand, int& nCmdLen)
{
CPacket* pPacket = pItem->GetPacket();
(pPacket->GetPrivateData()).n[2] = HLS_W_WRITE;
CString csPmessage;
IOITEMDEF * pItemStru = pItem->GetItemStru();
chCommand[0] = 0x3A; //写入帧头
CDevice* pDevice = pPacket->GetDevice();
CString csAddr = pDevice->GetAddr();
char byBuf[256];
int nTemp;
sscanf((const char *)csAddr,"%d",&nTemp);
sprintf(byBuf,"%02x",nTemp); //把十进制地址转化为十六进制字符串
chCommand[1] = byBuf[0]; //写入从机地址
chCommand[2] = byBuf[1];
chCommand[3] = 0x31;//写功能号
chCommand[4] = 0x30;
csPmessage+="写保持寄存器";
csPmessage+=":地址";
sprintf(byBuf,"%04x",pItemStru->n[1]);
chCommand[5] = byBuf[0]; //写入开始地址
chCommand[6] = byBuf[1];
chCommand[7] = byBuf[2];
chCommand[8] = byBuf[3];
csPmessage+=byBuf;
csPmessage+="H";
chCommand[9] = 0x30;
chCommand[10]= 0x30;
chCommand[11]= 0x30;
chCommand[12]= 0x31;
chCommand[13]= 0x30;
chCommand[14]= 0x32;
int nData;
sscanf(szWriteData,"%d",&nData);
sprintf(byBuf,"%04x",nData);
chCommand[15] = byBuf[0];
chCommand[16] = byBuf[1];
chCommand[17] = byBuf[2];
chCommand[18] = byBuf[3];
if(pDevice->GetCfgStru()->n[DEV_Model] == 0
&& pDevice->GetCfgStru()->n[DEV_Protocol] == 0)
{
BYTE bCheck = (BYTE)GetCheckCode(HLS_ASCII,chCommand,18);
sprintf(byBuf,"%02x",bCheck);
chCommand[19] = byBuf[0]; //写入校验码
chCommand[20] = byBuf[1];
chCommand[21] = 0x0D; //写入帧尾
chCommand[22] = 0x0A;
nCmdLen = 23;
chCommand[23] = '\0';
strupr(chCommand); //小写字母变为大写
}
else
{//只是为了转化成其他格式的命令,在这里不用生成校验
chCommand[19] = '\0';
strupr(chCommand);
nCmdLen = 19;
}
pDevice->ShowProcessMessage(csPmessage);
return SEND | WAIT;
}
。。。。
叶帆工作室:http://blog.csdn.net/yefanqiu