📄 plcdll.cpp
字号:
// plcdll.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
#include "plcdll.h"
#include "stdio.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define LoByte(x) ((char)((x) & 0x0F))//获取低位
#define HiByte(x) ((char)((x) >> 4))//获取高位
BYTE GetCheckCode(char * pSendBuf, int nEnd);//获得校验码
int OpenCom(int iCom,char *SendBuf);//串口打开
//
// Note!
//
// If this DLL is dynamically linked against the MFC
// DLLs, any functions exported from this DLL which
// call into MFC must have the AFX_MANAGE_STATE macro
// added at the very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
//
// It is very important that this macro appear in each
// function, prior to any calls into MFC. This means that
// it must appear as the first statement within the
// function, even before any object variable declarations
// as their constructors may generate calls into the MFC
// DLL.
//
// Please see MFC Technical Notes 33 and 58 for additional
// details.
//
/////////////////////////////////////////////////////////////////////////////
// CPlcdllApp
BEGIN_MESSAGE_MAP(CPlcdllApp, CWinApp)
//{{AFX_MSG_MAP(CPlcdllApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPlcdllApp construction
CPlcdllApp::CPlcdllApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CPlcdllApp object
CPlcdllApp theApp;
/* 程序功能:
核子秤的流量以4-20ma的形式输出。累计量以吨脉冲的形式输出。
输出介质台达DVP SS系列PLC。
编写时间:06-05-20。
北京市煤炭矿用机电设备开发公司
*/
int FlowOutput(int nCount,float fCurFlow,int nChannels,int iCom)
{
/*
函数说明:流量输出到PLC 的DA模块(4-20ma)
参数说明:nCount: 秤总数;
fCurrFlow: 各台秤的实时流量;
nChannels: 选择的通道;
最后修改日期:06-05-20
*///通信协议 例子 3A 30 31 30 35 30 43 30 30 46 46 30 30 45 46 0D 0A
char tdat[17],buf[4],LoTemp[1],HiTemp[1];
int iCurFlow=0;
iCurFlow=(int)fCurFlow;
sprintf(buf,"%04X",iCurFlow);
tdat[0]=0x3A;tdat[1]=0x30;tdat[2]=0x31;tdat[3]=0x30;tdat[4]=0x36;
tdat[5]=0x31;tdat[6]=0x30;tdat[7]=0x30;tdat[8]=0x41;tdat[15]=0x0D;tdat[16]=0x0A;
switch(nChannels)//D0-D11 寄存器的位置
{
case 0:
tdat[8]=0x30;
break;
case 1:
tdat[8]=0x31;
break;
case 2:
tdat[8]=0x32;
break;
case 3:
tdat[8]=0x33;
break;
case 4:
tdat[8]=0x34;
break;
case 5:
tdat[8]=0x35;
break;
case 6:
tdat[8]=0x36;
break;
case 7:
tdat[8]=0x37;
break;
case 8:
tdat[8]=0x38;
break;
case 9:
tdat[8]=0x39;
break;
case 10:
tdat[8]=0x41;
break;
case 11:
tdat[8]=0x42;
break;
}
tdat[9]=buf[0];
tdat[10]=buf[1];
tdat[11]=buf[2];
tdat[12]=buf[3];
BYTE A=GetCheckCode(tdat,13);//获得校验码
sprintf(LoTemp,"%X",LoByte(A));
sprintf(HiTemp,"%X",HiByte(A));
tdat[13]=HiTemp[0];
tdat[14]=LoTemp[0];
return OpenCom(iCom,tdat);
}
int SetParameterOffSet(int nChannels,int iEnactment,int iCom)
{
//功能:修改设定参OffSet(最小)
//参数:通道,设定值
//最后修改:06-9-20
char tdat[17],buf[4],LoTemp[1],HiTemp[1];
sprintf(buf,"%04X",iEnactment);
tdat[0]=0x3A;tdat[1]=0x30;tdat[2]=0x31;tdat[3]=0x30;tdat[4]=0x36;
tdat[5]=0x31;tdat[6]=0x30;tdat[7]=0x30;tdat[8]=0x41;tdat[15]=0x0D;tdat[16]=0x0A;
switch(nChannels)//D12-D23 寄存器的位置
{
case 0://D12
tdat[8]=0x43;
break;
case 1://D13
tdat[8]=0x44;
break;
case 2://D14
tdat[8]=0x45;
break;
case 3://D15
tdat[8]=0x46;
break;
case 4://D16
tdat[7]=0x31;
tdat[8]=0x30;
break;
case 5://D17
tdat[7]=0x31;
tdat[8]=0x31;
break;
case 6://D18
tdat[7]=0x31;
tdat[8]=0x32;
break;
case 7://D19
tdat[7]=0x31;
tdat[8]=0x33;
break;
case 8://D20
tdat[7]=0x31;
tdat[8]=0x34;
break;
case 9://D21
tdat[7]=0x31;
tdat[8]=0x35;
break;
case 10://D22
tdat[7]=0x31;
tdat[8]=0x36;
break;
case 11://D23
tdat[7]=0x31;
tdat[8]=0x37;
break;
}
tdat[9]=buf[0];
tdat[10]=buf[1];
tdat[11]=buf[2];
tdat[12]=buf[3];
BYTE A=GetCheckCode(tdat,13);//获得校验码
sprintf(LoTemp,"%X",LoByte(A));
sprintf(HiTemp,"%X",HiByte(A));
tdat[13]=HiTemp[0];
tdat[14]=LoTemp[0];
return OpenCom(iCom,tdat);
}
int SetParamentGain(int nChannels,int iEnactment,int iCom)
{
//功能:修改设定参数Gain(最大)
//参数:通道,设定值
//最后修改:06-9-20
char tdat[17],buf[4],LoTemp[1],HiTemp[1];
sprintf(buf,"%04X",iEnactment);
tdat[0]=0x3A;tdat[1]=0x30;tdat[2]=0x31;tdat[3]=0x30;tdat[4]=0x36;
tdat[5]=0x31;tdat[6]=0x30;tdat[8]=0x41;tdat[15]=0x0D;tdat[16]=0x0A;
switch(nChannels)//D24-D35 寄存器的位置
{
case 0://D24
tdat[7]=0x31;
tdat[8]=0x38;
break;
case 1://D25
tdat[7]=0x31;
tdat[8]=0x39;
break;
case 2://D26
tdat[7]=0x31;
tdat[8]=0x41;
break;
case 3://D27
tdat[7]=0x31;
tdat[8]=0x42;
break;
case 4://D28
tdat[7]=0x31;
tdat[8]=0x43;
break;
case 5://D29
tdat[7]=0x31;
tdat[8]=0x44;
break;
case 6://D30
tdat[7]=0x31;
tdat[8]=0x45;
break;
case 7://D31
tdat[7]=0x31;
tdat[8]=0x46;
break;
case 8://D32
tdat[7]=0x32;
tdat[8]=0x30;
break;
case 9://D33
tdat[7]=0x32;
tdat[8]=0x31;
break;
case 10://D34
tdat[7]=0x32;
tdat[8]=0x32;
break;
case 11://D35
tdat[7]=0x32;
tdat[8]=0x33;
break;
}
tdat[9]=buf[0];
tdat[10]=buf[1];
tdat[11]=buf[2];
tdat[12]=buf[3];
BYTE A=GetCheckCode(tdat,13);//获得校验码
sprintf(LoTemp,"%X",LoByte(A));
sprintf(HiTemp,"%X",HiByte(A));
tdat[13]=HiTemp[0];
tdat[14]=LoTemp[0];
return OpenCom(iCom,tdat);
}
BYTE GetCheckCode(char *pSendBuf,int nEnd)//获得校验码
{
BYTE byLrc = 0;
char pBuf[4];
int nData = 0;
for(int i=1; i<nEnd; i+=2) //i初始为1,避开“开始标记”冒号
{
//每两个需要发送的ASCII码转化为一个十六进制数
pBuf [0] = pSendBuf [i];
pBuf [1] = pSendBuf [i+1];
pBuf [2] = '\0';
sscanf(pBuf,"%x",&nData);
byLrc += nData;
}
byLrc = ~ byLrc;
byLrc ++;
return byLrc;
}
int OpenCom(int iCom,char *SendBuf)
{
HANDLE hcomm;//串口句柄
DWORD dwError;
DWORD dwBytesRead = 0;
char strCom[4]={'C','O','M','3',};
sprintf(strCom,"COM%d",iCom);
hcomm =CreateFile(strCom,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hcomm==INVALID_HANDLE_VALUE)
{
dwError=GetLastError();
return 1;
}
SetupComm(hcomm,100,100);
DCB dcb;
BOOL bErr;
bErr=GetCommState(hcomm,&dcb);//获取dcb结构
if(bErr==0)
{
dwError=GetLastError();
return 2;
}
dcb.BaudRate=9600;//波特率
dcb.fParity=TRUE;//是否校验
dcb.ByteSize=7;//数据位
dcb.Parity=EVENPARITY;//偶校验
dcb.StopBits=ONESTOPBIT;//停止位
bErr=SetCommState(hcomm,&dcb);//设置dcb
if(bErr==0)
{
dwError=GetLastError();
return 2;
}
COMMTIMEOUTS timeout;//超时设置
bErr=GetCommTimeouts(hcomm,&timeout);
if(bErr==0)
{
dwError=GetLastError();
return 2;
}
timeout.WriteTotalTimeoutConstant=200;
timeout.WriteTotalTimeoutMultiplier=200;
bErr=SetCommTimeouts(hcomm,&timeout);
if(bErr==0)
{
dwError=GetLastError();
return 2;
}
FlushFileBuffers(hcomm);
if(!WriteFile(hcomm,SendBuf,17,&dwBytesRead,NULL))
return 3;
CloseHandle(hcomm);
return 0;
}
int TotalOutOpen(int nCount,float *Total,int iChannel,int iCom)
{
//功能:使通道打开置1(通信协议,请参看PLC附录)
//最后修改:06-9-19
char tdat[17];
tdat[0]=0x3A;tdat[1]=0x30;tdat[2]=0x31;tdat[3]=0x30;tdat[4]=0x35;tdat[5]=0x30;
tdat[6]=0x43;tdat[9]=0x46;tdat[10]=0x46;tdat[11]=0x30;tdat[12]=0x30;tdat[15]=0x0D;
tdat[16]=0x0A;
switch(iChannel)
{
case 0:
tdat[7]=0x30;tdat[8]=0x30;tdat[13]=0x45;tdat[14]=0x46;//Y0通道1024
break;
case 1:
tdat[7]=0x30;tdat[8]=0x31;tdat[13]=0x45;tdat[14]=0x45;//Y1通道1025
break;
case 2:
tdat[7]=0x30;tdat[8]=0x32;tdat[13]=0x45;tdat[14]=0x44;//Y2通道1026
break;
case 3:
tdat[7]=0x30;tdat[8]=0x33;tdat[13]=0x45;tdat[14]=0x43;//Y3通道1027
break;
case 4:
tdat[7]=0x30;tdat[8]=0x34;tdat[13]=0x45;tdat[14]=0x42;//Y4通道1028
break;
case 5:
tdat[7]=0x30;tdat[8]=0x35;tdat[13]=0x45;tdat[14]=0x41;//Y5通道1029
break;
case 6:
tdat[7]=0x30;tdat[8]=0x36;tdat[13]=0x45;tdat[14]=0x39;//Y20通道1030
break;
case 7:
tdat[7]=0x30;tdat[8]=0x38;tdat[13]=0x45;tdat[14]=0x37;//Y21通道M1032--0C08
break;
case 8:
tdat[7]=0x30;tdat[8]=0x39;tdat[13]=0x45;tdat[14]=0x36;//Y22通道1033--0C09
break;
case 9:
tdat[7]=0x30;tdat[8]=0x42;tdat[13]=0x45;tdat[14]=0x34;//Y23通道1035--0C11
break;
case 10:
tdat[7]=0x30;tdat[8]=0x43;tdat[13]=0x45;tdat[14]=0x33;//Y24通道1036--0C12
break;
case 11:
tdat[7]=0x30;tdat[8]=0x44;tdat[13]=0x45;tdat[14]=0x32;//Y25通道1037--0C13
break;
case 12:
tdat[7]=0x30;tdat[8]=0x45;tdat[13]=0x45;tdat[14]=0x31;//Y26通道1038--0C14
break;
case 13:
tdat[7]=0x30;tdat[8]=0x46;tdat[13]=0x45;tdat[14]=0x30;//Y27通道1039--0C15
break;
default:
break;
}
OpenCom(iCom,tdat);
return 0;
}
int TotalOutClose(int nCount,float *Total,int iChannel,int iCom)
{
//功能:使通道打开置0
//最后修改:06-9-19
char tdat[17];
tdat[0]=0x3A;tdat[1]=0x30;tdat[2]=0x31;tdat[3]=0x30;tdat[4]=0x35;tdat[5]=0x30;
tdat[6]=0x43;tdat[9]=0x30;tdat[10]=0x30;tdat[11]=0x30;tdat[12]=0x30;tdat[15]=0x0D;
tdat[16]=0x0A;
switch(iChannel)
{
case 0:
tdat[7]=0x30;tdat[8]=0x30;tdat[13]=0x45;tdat[14]=0x45;//Y0通道1024
break;
case 1:
tdat[7]=0x30;tdat[8]=0x31;tdat[13]=0x45;tdat[14]=0x44;//Y1通道1025
break;
case 2:
tdat[7]=0x30;tdat[8]=0x32;tdat[13]=0x45;tdat[14]=0x43;//Y2通道1026
break;
case 3:
tdat[7]=0x30;tdat[8]=0x33;tdat[13]=0x45;tdat[14]=0x42;//Y3通道1027
break;
case 4:
tdat[7]=0x30;tdat[8]=0x34;tdat[13]=0x45;tdat[14]=0x41;//Y4通道1028
break;
case 5:
tdat[7]=0x30;tdat[8]=0x35;tdat[13]=0x45;tdat[14]=0x39;//Y5通道1029
break;
case 6:
tdat[7]=0x30;tdat[8]=0x36;tdat[13]=0x45;tdat[14]=0x38;//Y20通道1030
break;
case 7:
tdat[7]=0x30;tdat[8]=0x38;tdat[13]=0x45;tdat[14]=0x36;//Y21通道M1032--0C08
break;
case 8:
tdat[7]=0x30;tdat[8]=0x39;tdat[13]=0x45;tdat[14]=0x35;//Y22通道1033--0C09
break;
case 9:
tdat[7]=0x30;tdat[8]=0x42;tdat[13]=0x45;tdat[14]=0x33;//Y23通道1035--0C11
break;
case 10:
tdat[7]=0x30;tdat[8]=0x43;tdat[13]=0x45;tdat[14]=0x32;//Y24通道1036--0C12
break;
case 11:
tdat[7]=0x30;tdat[8]=0x44;tdat[13]=0x45;tdat[14]=0x31;//Y25通道1037--0C13
break;
case 12:
tdat[7]=0x30;tdat[8]=0x45;tdat[13]=0x45;tdat[14]=0x30;//Y26通道1038--0C14
break;
case 13:
tdat[7]=0x30;tdat[8]=0x46;tdat[13]=0x44;tdat[14]=0x46;//Y27通道1039--0C15
break;
default:
break;
}
OpenCom(iCom,tdat);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -