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

📄 readme.txt

📁 利用VC编写的关于配料的动态库程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
========================================================================
       DYNAMIC LINK LIBRARY : comm
========================================================================


AppWizard has created this comm DLL for you.  

This file contains a summary of what you will find in each of the files that
make up your comm application.

comm.dsp
    This file (the project file) contains information at the project level and
    is used to build a single project or subproject. Other users can share the
    project (.dsp) file, but they should export the makefiles locally.

comm.cpp
    This is the main DLL source file.

comm.h
    This file contains your DLL exports.

/////////////////////////////////////////////////////////////////////////////
Other standard files:

StdAfx.h, StdAfx.cpp
    These files are used to build a precompiled header (PCH) file
    named comm.pch and a precompiled types file named StdAfx.obj.


/////////////////////////////////////////////////////////////////////////////
Other notes:

AppWizard uses "TODO:" to indicate parts of the source code you
should add to or customize.


/////////////////////////////////////////////////////////////////////////////

// comm.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "comm.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"

int ExecSQL(char *SqlText);
int SelectSQL(char *SqlText, int n, char Ret[][200], int *RowCount);
int SaveData(int k);
int GetPF(char *pfbh, float pzl);

struct PF{
	int xh;
	int ch;
	int jlh;
	char mc[30];
	float bl;
	float llz;
	long hh;
	float tql;
	float tql0;
	float sjz;
	float csz;
	float xsz;
              } pf1[5][7],pf2[5][7],pf3[5][7],pf4[5][7],pf5[5][7];

static int end1[5],end2[5],end3[5],end4[5],end5[5], ppend;
static int start1, pover1, pl1 ,pp, stch[6];
static int start2, pover2, pl2;
static int start3, pover3, pl3;
static int start4, pover4, pl4;
static int start5, pover5, pl5;
static float w_jcz1, ybwc1, bpz1;
static float w_jcz2, ybwc2, bpz2;
static float w_jcz3, ybwc3, bpz3;
static float w_jcz4, ybwc4, bpz4;
static float w_jcz5, ybwc5, bpz5;
static int fl_n1,fl_n2,fl_n3,fl_n4,fl_n5;
static int fl_end1,fl_end2,fl_end3,fl_end4,fl_end5;
static float pzl;
static int scpf_XH=1, hfjh, hhsj;
char pfbh[10],pfmc[30];
static BOOL tql_chk=0, tql_mod=0;

HANDLE m_hComFile;

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

//=================================================
void delay(long DealyTime)
{
	SYSTEMTIME sysTime;
	long End_time, Start_time;

	GetLocalTime(&sysTime);
	Start_time= (sysTime.wHour*3600 + sysTime.wMinute*60 + 
				sysTime.wSecond)*1000 + sysTime.wMilliseconds;
	End_time=Start_time;
	while((End_time-Start_time) < DealyTime) 
	{
	 GetLocalTime(&sysTime);
	 End_time= (sysTime.wHour*3600 + sysTime.wMinute*60 + 
				sysTime.wSecond)*1000 + sysTime.wMilliseconds;
	}
}
//=================================================
int CloseCom(void)
{
  if(m_hComFile==0)return 0;
  CloseHandle(m_hComFile);
  m_hComFile=0;
  return 0;
}
//=================================================
int SetCom(char *comport)
{
DCB dcb ; //定义设备控制块结构 
COMMTIMEOUTS timeouts ; //定义超时结构,并填写该结构 
char Msg[30];

/*1. 打开串行通信设备。在VC中使用CreateFile函数打开串口,CreateFile将返回串口的句柄。
该句柄将被用于后续的通信操作,并贯穿整个通信过程。当采用异步方式时,
CreateFile函数的参数fdwAttrsAndFlags必须设为FILE_FLAG_ OVERLAPPED*/
m_hComFile =CreateFile(comport, 
					GENERIC_READ | GENERIC_WRITE, // 允许读写操作 
					0,	//此项必须为0 
					NULL, // 安全设置 
					OPEN_EXISTING,	//设置打开方式 
					FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//FILE_FLAG_OVERLAPPED, //使用异步通信标志 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED
					NULL ); 
strcpy(Msg,comport);
strcat(Msg, "通信口打开错误!");
if(m_hComFile<=0) 
{
	MessageBox(NULL,"错误信息",Msg,MB_OK);
	return 1;
}


/*2. 指定并初始化读写缓冲区。程序通过调用SetupComm函数来指定读写缓冲区的大小,
并执行重新分配内部输入和输出缓冲的任务,用PurgeComm函数对输入和输出缓冲进行初始化*/
//设置事件驱动的类型
SetCommMask(m_hComFile, EV_RXCHAR | EV_TXEMPTY ); 
//设置输入、输出缓冲区的大小
SetupComm(m_hComFile, 1024,1024) ;  
//清空输入、输出缓冲区
PurgeComm(m_hComFile, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );

/*3.设置串口属性,配置DCB结构。当用CreateFile函数完成串口打开操作时,
默认继承设备控制块(DCB结构)设置。通过调用GetCommState函数读取当前串口设备控制块DCB设置,
修改后通过SetCommState函数将其写入。也可以使用GetCommProperties获取COMMPROP结构,
其中记载了系统支持的各项设置,包括当前所使用的串行设备、数据传输波特率、输入输出缓冲区大小等。*/
GetCommState(m_hComFile, &dcb ) ; //读取串口原来的参数设置 
dcb.BaudRate =9600; 
dcb.ByteSize =7; 
dcb.Parity = EVENPARITY; 
dcb.StopBits = ONESTOPBIT ; 
//dcb.fBinary = TRUE ; 
//dcb.fParity = FALSE; 
SetCommState(m_hComFile, &dcb ) ; //串口参数配置 
/*4. 设置超时值。串口打开后,I/O操作的超时值采用默认值。超时值的设置与结构COMMTIMEOUTS及
函数GetCommTimeouts和SetCommTimeouts有关。用GetCommTimeouts函数可以获得当前I/O操作的超时
值配置,而调用SetCommTimeouts函数可以修改此配置,*/
timeouts.ReadIntervalTimeout = 1000; 
timeouts.ReadTotalTimeoutMultiplier = 100; 
timeouts.ReadTotalTimeoutConstant = 3000; 
timeouts.WriteTotalTimeoutMultiplier = 1; 
timeouts.WriteTotalTimeoutConstant=2000;
SetCommTimeouts(m_hComFile, &timeouts);		//设置读写操作所允许的超时 
/*其中,区间超时(ReadIntervalTimeout)指的是在读取两个字符之间的时间间隔,它仅对从端口中
读取数据有效;总超时指的是当读或写特定的字节数需要的总时间超过某一阈值时,超时触发。
超时的计算公式如下: 
ReadTotalTimeout= (ReadTotalTimeoutMultiplier * bytes_to_read)+ ReadToTaltimeoutConstant 
WriteTotalTimeout = (WriteTotalTimeoutMuliplier * bytes_to_write) + WritetoTotalTimeoutConstant */
return 0;
}
//=====================================================
int yb_tx(char *ComSend, char *ComRecceive, long delaytime)
{
BOOL fWriteStat;
OVERLAPPED overwrite,overread; 
BOOL fReadStat;
DWORD dwBytesToWrite, dwBytesWritten;
DWORD dwLength,dwBytesRead;
char lpBuffer[5];
long k=0, ErrCode=0;

if(m_hComFile==0) 
	{
//	MessageBox(NULL,"通信口没有打开!","错误信息",MB_OK);
	return 1;
	}
// *ComSend 存放待发送的数据 

//清空输入、输出缓冲区
PurgeComm(m_hComFile, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); 

/*5. 进行串行数据通信。调用函数ReadFile和WriteFile读写串口。若采用异步通信方式,
两函数中最后一个参数为指向OVERLAPPED结构的非空指针,在读写函数返回值为FALSE的情况下,
调用GetLastError函数,返回值为ERROR_IO_PENDING,表明I/O操作悬挂,即操作转入后台继续执行。
此时,可以用WaitForSingleObject函数来等待结束信号并设置最长等待时间。下面的例子中,
在主线程中发送命令,用一个辅助线程来监视串口,有数据到达时依靠事件驱动读入数据并向主线程报告。*/


//设置用于异步操作的OVERLAPPED结构 
overwrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 
//写数据
dwBytesToWrite=strlen(ComSend);	//要发送的数据的长度
fWriteStat = WriteFile(m_hComFile, ComSend, dwBytesToWrite, &dwBytesWritten, &overwrite); 
if (!fWriteStat){ 
	if (GetLastError() == ERROR_IO_PENDING) 
		{//MessageBox(NULL,"发送数据错误!","错误信息",MB_OK);
	} 
	}
//延时读
delay(delaytime);
//读数据
overread.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 
dwLength=1;
lpBuffer[0]=0;
ComRecceive[0]=0;
while(lpBuffer[0]!=10)
{
 k++;
 fReadStat = ReadFile(m_hComFile,lpBuffer,dwLength, &dwBytesRead,&overread);
 if (!fReadStat){
	if (GetLastError() == ERROR_IO_PENDING)
	{
	// MessageBox(NULL,"未接收到数据,请加大延时时间","错误信息",MB_OK); 
	} 
	}
 if(k>100) break;
 if(dwBytesRead>0)
	{
	lpBuffer[1]=0;
	strcat(ComRecceive,lpBuffer);
	}
}
 //MessageBox(NULL,ComRecceive,"已经接收的数据",MB_OK);

return 0;
}
//=============================================
int yb_read(int id, double *zl)
{
	char yb_id[]={5,'I','D','1','8',13,10,0};
	char yb_send[]={'R','E','A','D',13,10,0};
	char yb_out[30];
	int len;
	
	if(id==2)yb_id[3]='2';
	if(id==3)yb_id[3]='3';
	if(id==4)yb_id[3]='4';
	if(id==5)yb_id[3]='5';
	yb_tx(yb_id, yb_out,100);
	yb_tx(yb_send, yb_out,100);
	len=strlen(yb_out);
	yb_out[len-4]=0;
	*zl=atof(&yb_out[7]);
	if(yb_out[6]=='-') *zl=-(*zl);

	return 0;
}
//=============================================
int yb_write(int id, long yb_hh, long yb_hi, long yb_ll)
{
	char yb_set0[]={5,'I','D','1','8',13,10,0};
	char yb_set1[11][20];
	char crlf[3]={13,10,0};
	char yb_out[30];
	int k, Ret;
	long yb_lo;
	char ss[50];

	if(id==2)yb_set0[3]='2';
	if(id==3)yb_set0[3]='3';
	if(id==4)yb_set0[3]='4';
	if(id==5)yb_set0[3]='5';
	

	if(yb_ll<0) yb_ll=0;
	if(yb_hi<yb_ll) yb_hi=yb_ll;

	if(yb_hh<yb_hi)
	{ 
	 sprintf(ss, "%d号仪表 %ld %ld %ld", id, yb_hh,yb_hi,yb_ll);
	 MessageBox(NULL,ss ,"仪表设置数据错误",MB_OK);
	 return 1;
	}

	//设置仪表数据
	yb_tx(yb_set0, yb_out,100);
	strcpy(yb_set1[0],"SET");
	sprintf(yb_set1[1],"%ld", yb_hh);

	strcpy(yb_set1[2],"N");
	sprintf(yb_set1[3],"%ld", yb_hi);

	yb_lo=(yb_hi+yb_ll)/2;
	strcpy(yb_set1[4],"N");
	sprintf(yb_set1[5],"%ld", yb_lo);

	strcpy(yb_set1[6],"N");
	sprintf(yb_set1[7],"%ld", yb_ll);

	strcpy(yb_set1[8],"N");
	sprintf(yb_set1[9],"R");

 sprintf(ss, "%d   %ld %ld %ld", id, yb_hh,yb_hi,yb_ll);
 //MessageBox(NULL,ss , "仪表数据",MB_OK);
	//设置数据
	for(k=0;k<10;k++)
	{
	//	MessageBox(NULL,yb_set1[k], "仪表数据",MB_OK);
		strcat(yb_set1[k],crlf);
		yb_tx(yb_set1[k], yb_out,150);
	}
	if(yb_out[0]=='Y' && yb_out[1]=='E' && yb_out[2]=='S') 
		Ret = 0;
	else
		Ret = 1;
	return Ret;
}
// This is an example of an exported variable
COMM_API int nComm=0;

// This is an example of an exported function.
COMM_API int fnComm(void)
{
	return 42;
}

// This is the constructor of a class that has been exported.
// see comm.h for the class definition
CComm::CComm()
{ 
	return; 
}
//================================================
//*pl0-- ==0:每批次的第一个下料仓开始下料,==1:第二批以后或不检测提前量的任意批次正在下料
// ==2:检测提前量的第一批正在下料,==3:检测提前量第一批的某个仓停止下料
void ppll(int ybid, struct PF pf0[10], int *start0,int end0, float ybwc0, float bpz0, 
		  int p0,int *stch0, int *pl0,  int *pover, float w_jcz, float jd, int *ybset)
{
 double zl;
 long hh,hi,ll;
 int mm;
 char ss[30];

 if(*pover==1) return;
 if(*stch0==0 && (*pl0==0 || *pl0==3))
  {
    if(*pl0==3 && *start0==end0) //检测提前量第一批的最后一个仓停止下料
		{
		//读仪表
		yb_read(ybid, &zl);
		//存储第一批最后一个仓的实际值
		pf0[*start0].sjz = (float)zl-pf0[*start0].csz;
		pf0[*start0].xsz = (float)zl-pf0[*start0].sjz;

		//存储实际值
		SaveData(ybid);	
		if(tql_mod==1) pf0[*start0].tql= ((float)(zl-pf0[*start0].hh/jd) + pf0[*start0].tql)/2;

		*pl0=0;
		*pover=1;
		return;
		}
	if(p0==1 && tql_chk) //检测提前量第一批的某个仓停止下料
		//第一批	
		{
		//读仪表
		yb_read(ybid, &zl);
		if(*pl0==3) 
			{
			 pf0[*start0].sjz = (float)zl-pf0[*start0].csz;
			 pf0[*start0].xsz = (float)zl-pf0[*start0].sjz;
			 //存实际数值
			 SaveData(ybid);
			 if(tql_mod==1)pf0[*start0].tql= ((float)(zl-pf0[*start0].hh/jd) + pf0[*start0].tql)/2;
			 *start0=*start0+1;
			}
		pf0[*start0].csz = (float)zl;
		//设置第一批仪表检测提前量的数据
		hh=(long)((pf0[*start0].csz+w_jcz)*jd);
		pf0[*start0].hh=hh;
		hi=(long)(zl*jd);
		ll=hi;
		mm=yb_write(ybid, hh, hi, ll);
		if(mm==1) 
		{
		 MessageBox(NULL,"数据设置错误","错误信息",MB_OK);
		 return;
		}
		//正在配料
		*pl0=2;	
		//启动绞龙
		*stch0=pf0[*start0].jlh;
		*ybset=1;
		return ;
	}
   //第二批以后或不检测提前量的任意批次
   if(p0>1 || tql_chk==0)
    {
     //读仪表
     yb_read(ybid, &zl);
     pf0[*start0].csz=(float)zl;
     //设置仪表的目标数据
     hh=(long)((pf0[*start0].csz+pf0[*start0].llz-pf0[*start0].tql)*jd);
	 pf0[*start0].hh=hh;
     hi=hh-(long)(bpz0*jd);
     ll=(long)(ybwc0*jd);
     mm=yb_write(ybid, hh , hi,  ll);
	 if(mm==1) 
	 {
		 MessageBox(NULL,"数据设置错误","ASFSDAF",MB_OK);
		 return;
	 }
    //正在配料
     *pl0=1;	
    //启动绞龙
     *stch0=pf0[*start0].jlh;
	 *ybset=1;
	 return ;
   }
 }
 //---------如果配料绞龙停
 if( *stch0==0 && (*pl0==1 || *pl0==2))
    {
    //读仪表
    yb_read(ybid, &zl);
	//第二批以后最后一个下料仓或不检测提前量的任意批的最后一个下料仓
	if(*start0 == end0 && (p0>1 || tql_chk==0))	
		{
		pf0[*start0].sjz = (float)zl-pf0[*start0].csz;
		pf0[*start0].xsz = (float)zl-pf0[*start0].sjz;
		//存储实际值
		SaveData(ybid);	
		//下一批的提前量
		if(tql_mod==1) pf0[*start0].tql= ((float)(zl-pf0[*start0].hh/jd) + pf0[*start0].tql)/2;
		*pl0=0;
		*pover=1;

		//此秤配料完成
		sprintf(ss,"批次=%d   start0=%d   end0=%d", p0, *start0, end0);
		MessageBox(NULL,ss,"此秤配料完成!",MB_OK);
		
		return;
		}
    if( (*start0 < end0) || (*start0 == end0 && p0==1 && tql_chk))
		{
		//设置仪表的目标数据
		if(*pl0==1) //如果是第二批以后则start0+1
			{
			//实际值
			pf0[*start0].sjz = (float)zl-pf0[*start0].csz;
			pf0[*start0].xsz = (float)zl-pf0[*start0].sjz;
			//存储实际值
			SaveData(ybid);
			//下一批的提前量
			if(tql_mod==1) pf0[*start0].tql= ((float)(zl-pf0[*start0].hh/jd) + pf0[*start0].tql)/2;

			*start0=*start0+1;
			pf0[*start0].csz = (float)zl;
			}
		hh=(long)((pf0[*start0].csz+pf0[*start0].llz-pf0[*start0].tql)*jd);
		pf0[*start0].hh=hh;
		hi=(long)(hh-bpz0*jd);
		ll=(long)(ybwc0*jd);
		mm=yb_write(ybid, hh, hi,  ll);
		if(mm==1) 
			{
			MessageBox(NULL,"数据设置错误","错误信息",MB_OK);
			return;
			}
		//正在配料
		if(*pl0==2) *pl0=3;	
		//启动绞龙
		*stch0=pf0[*start0].jlh;
		*ybset=1;
	}
  }
 //-----------停绞龙处理完毕
}
//==============================
void pp_init(void)
{
	fl_n1=1;
	fl_n2=1;
	fl_n3=1;
	fl_n4=1;
	fl_n5=1;

	pover1=0;
	pover2=0;
	pover3=0;
	pover4=0;
	pover5=0;

	start1=1;
	start2=1;
	start3=1;
	start4=1;
	start5=1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -