⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plcdll.cpp

📁 是一个和台达的通信DLL 还不是很完善
💻 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 + -