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

📄 comm.cpp

📁 利用VC编写的关于配料的动态库程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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 GetPF(int xh, char *pfbh0, float pzl0, int chn[2], float *tjjzl, float *oilzl, int *oilmc, float *oildw);//函数声明
void SaveXL();
 
struct TJJ{
 int bh;
 char mc[40];
 float llz;
 float sjz;
 float xsz;
 int n;
 }tjj[50]; //定义结构体TJJ,TJJ类型一维数组tjj
 
struct PF{
 int xh;
 int ch;
 int jlh;
 char mc[30];
 float bl;
 float llz;///////////
 long hh;
 long hi;
 long ll;
 float tql;//////////////
 float tql0;
 float bpz;//////////////
 float sjz;
 float csz;
 float xsz;
 float bjwc;///////////////
 float yxwc;/////////////////
              } pf1[5][20],pf2[5][20],pf3[5][20],pf4[5][20],pf5[5][20];//定义结构体PF,PF类型二维数组pf1,pf2,pf3,pf4,pf5
 
static int end1[5],end2[5],end3[5],end4[5],end5[5], ppend1, ppend2; //定义一维整数数组用于保存每个仪表称的称重次数
static int start1, pover1, pl1 ,pp1,pp2, stch[6]; //定义一号系统的开始及批次数据
//static int start10, start20; 
static int start2, pover2, pl2; 
static int start3, pover3, pl3;
static int start4, pover4, pl4;
static int start5, pover5, pl5;
static float w_jcz1;//仪表检测值,误差值,变频值
static float w_jcz2;
static float w_jcz3;
static float w_jcz4;
static float w_jcz5;
static float w_jcz6;
static float ybwc1,ybwc2,ybwc3,ybwc4,ybwc5,ybwc6;
static int hc_sj, hhj1_flsj, hhj2_flsj;
static int hcd1_flsj, hcd2_flsj;
static int c5_flsj, c6_flsj;
static int  c_flsj, cm_sj, hhm_sj;
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 pzl1,pzl2;
static int scpf_XH=1, hhsj1,hhsj2;
char pfbh1[5],pfmc1[30],pfbh2[5],pfmc2[30];
static BOOL tql_chk=0, tql_mod=0;
static int PL_END1, PL_END2;
static HANDLE m_hComFile=0, m_hCom1=0, m_hCom2=0, m_hCom3=0, m_hCom4=0, m_hCom5=0, m_hCom6=0;
 
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;
}
// 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; 
}
//=================================================
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*/
if(m_hComFile!=0) return 0;
m_hComFile =CreateFile(comport, 
     GENERIC_READ | GENERIC_WRITE, // 允许读写操作 
     0, //此项必须为0 
     NULL, // 安全设置 
     OPEN_EXISTING, //设置打开方式 
     NULL, //FILE_ATTRIBUTE_NORMAL|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, 128,128) ;  
//清空输入、输出缓冲区
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 = 1000; 
timeouts.WriteTotalTimeoutMultiplier = 1; 
timeouts.WriteTotalTimeoutConstant=1000;
SetCommTimeouts(m_hComFile, &timeouts);  //设置读写操作所允许的超时 
/*其中,区间超时(ReadIntervalTimeout)指的是在读取两个字符之间的时间间隔,它仅对从端口中
读取数据有效;总超时指的是当读或写特定的字节数需要的总时间超过某一阈值时,超时触发。
超时的计算公式如下: 
ReadTotalTimeout= (ReadTotalTimeoutMultiplier * bytes_to_read)+ ReadToTaltimeoutConstant 
WriteTotalTimeout = (WriteTotalTimeoutMuliplier * bytes_to_write) + WritetoTotalTimeoutConstant */
return 0;
}
//=================================================
int CloseCom1(char *Com)
{
  if(strcmp(Com, "com1")==0) CloseHandle(m_hCom1);
  if(strcmp(Com, "com2")==0) CloseHandle(m_hCom2);
  if(strcmp(Com, "com3")==0) CloseHandle(m_hCom3);
  if(strcmp(Com, "com4")==0) CloseHandle(m_hCom4);
  if(strcmp(Com, "com5")==0) CloseHandle(m_hCom5);
  if(strcmp(Com, "com6")==0) CloseHandle(m_hCom6);
  return 0;
}
//=====================================================
//Parity==0, NOPARITY(无效验);==1, ODDPARITY(奇效验);==2, EVENPARITY(偶效验)
int SetCom1(char *comport, int BaudRate, int Parity, int ByteSize)
{
DCB dcb ; //定义设备控制块结构 
COMMTIMEOUTS timeouts ; //定义超时结构,并填写该结构 
char Msg[30];
HANDLE m_hCom=0;
 
/*1. 打开串行通信设备。在VC中使用CreateFile函数打开串口,CreateFile将返回串口的句柄。
该句柄将被用于后续的通信操作,并贯穿整个通信过程。当采用异步方式时,
CreateFile函数的参数fdwAttrsAndFlags必须设为FILE_FLAG_ OVERLAPPED*/
if(m_hCom!=0) return 0;
m_hCom =CreateFile(comport, 
     GENERIC_READ | GENERIC_WRITE, // 允许读写操作 
     0, //此项必须为0 
     NULL, // 安全设置 
     OPEN_EXISTING, //设置打开方式 
     NULL, //FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//使用异步通信标志 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED
     NULL ); 
strcpy(Msg,comport);
strcat(Msg, "通信口打开错误!");
if(m_hCom<=0) 
{
 MessageBox(NULL,"错误信息",Msg,MB_OK);
 return 1;
}
 
/*2. 指定并初始化读写缓冲区。程序通过调用SetupComm函数来指定读写缓冲区的大小,
并执行重新分配内部输入和输出缓冲的任务,用PurgeComm函数对输入和输出缓冲进行初始化*/
//设置事件驱动的类型
SetCommMask(m_hCom, EV_RXCHAR | EV_TXEMPTY ); 
//设置输入、输出缓冲区的大小
SetupComm(m_hCom, 128,128) ;  
//清空输入、输出缓冲区
PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
 
/*3.设置串口属性,配置DCB结构。当用CreateFile函数完成串口打开操作时,
默认继承设备控制块(DCB结构)设置。通过调用GetCommState函数读取当前串口设备控制块DCB设置,
修改后通过SetCommState函数将其写入。也可以使用GetCommProperties获取COMMPROP结构,
其中记载了系统支持的各项设置,包括当前所使用的串行设备、数据传输波特率、输入输出缓冲区大小等。*/
GetCommState(m_hCom, &dcb ) ; //读取串口原来的参数设置 
dcb.BaudRate =BaudRate; 
dcb.ByteSize =ByteSize; 
dcb.Parity = Parity; 
dcb.StopBits = ONESTOPBIT ; 
//dcb.fBinary = TRUE ; 
//dcb.fParity = FALSE; 
SetCommState(m_hCom, &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_hCom, &timeouts);  //设置读写操作所允许的超时 
/*其中,区间超时(ReadIntervalTimeout)指的是在读取两个字符之间的时间间隔,它仅对从端口中
读取数据有效;总超时指的是当读或写特定的字节数需要的总时间超过某一阈值时,超时触发。
超时的计算公式如下: 
ReadTotalTimeout= (ReadTotalTimeoutMultiplier * bytes_to_read)+ ReadToTaltimeoutConstant 
WriteTotalTimeout = (WriteTotalTimeoutMuliplier * bytes_to_write) + WritetoTotalTimeoutConstant */
if(strcmp(comport, "com1")==0) m_hCom1=m_hCom;
if(strcmp(comport, "com2")==0) m_hCom2=m_hCom;
if(strcmp(comport, "com3")==0) m_hCom3=m_hCom;
if(strcmp(comport, "com4")==0) m_hCom4=m_hCom;
if(strcmp(comport, "com5")==0) m_hCom5=m_hCom;
if(strcmp(comport, "com6")==0) m_hCom6=m_hCom;
return 0;
}
//=====================================================
int yb_tx1(char *Com, char *ComSend, char *ComRecceive, long delaytime, int sendlen)
{
BOOL fWriteStat;
OVERLAPPED overwrite,overread; 
BOOL fReadStat;
DWORD dwBytesToWrite, dwBytesWritten;
DWORD dwLength,dwBytesRead;
char lpBuffer[5],ss[50];
long k=0, ErrCode=0;
 
HANDLE m_hCom=0;
 
if(strcmp(Com, "com1")==0) m_hCom=m_hCom1;
if(strcmp(Com, "com2")==0) m_hCom=m_hCom2;
if(strcmp(Com, "com3")==0) m_hCom=m_hCom3;
if(strcmp(Com, "com4")==0) m_hCom=m_hCom4;
if(strcmp(Com, "com5")==0) m_hCom=m_hCom5;
if(strcmp(Com, "com6")==0) m_hCom=m_hCom6;
 
if(m_hCom==0) 
 {
// MessageBox(NULL,"通信口没有打开!","错误信息",MB_OK);
 return 1;
 }
// *ComSend 存放待发送的数据 
 
//清空输入、输出缓冲区
PurgeComm(m_hCom, 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=sendlen; //要发送的数据的长度
//fWriteStat = WriteFile(m_hCom, ComSend, dwBytesToWrite, &dwBytesWritten, &overwrite); 
fWriteStat = WriteFile(m_hCom, ComSend, dwBytesToWrite, &dwBytesWritten, NULL); 
 
//sprintf(ss,"%d",dwBytesWritten);
//MessageBox(NULL,ComSend,ss,MB_OK);
 
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_hCom,lpBuffer,dwLength, &dwBytesRead,&overread);
 fReadStat = ReadFile(m_hCom,lpBuffer,dwLength, &dwBytesRead, NULL);
 if (!fReadStat){
 if (GetLastError() == ERROR_IO_PENDING)
 {
 MessageBox(NULL,"未接收到数据,请加大延时时间","错误信息",MB_OK); 
 } 
 }
 if(k>30) break;
 if(dwBytesRead>0)
 {
 lpBuffer[1]=0;
 strcat(ComRecceive,lpBuffer);
 }
}
// MessageBox(NULL,ComRecceive,"已经接收的数据",MB_OK);
*/
return 0;
}
//=====================================================
int yb_tx(int id, 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;
//==================== 绕过晚上12点 ===============================
  char strTime[30];
 
  SYSTEMTIME sysTime;
 
  GetLocalTime(&sysTime);
  while(sysTime.wHour==23 && sysTime.wMinute==59 && (sysTime.wSecond>57))
  {
   GetLocalTime(&sysTime);
  }
//=================================================================
  if(id==1) m_hComFile = m_hCom1;
  if(id==2) m_hComFile = m_hCom2;
  if(id==3) m_hComFile = m_hCom3;
  if(id==4) m_hComFile = m_hCom4;
 
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); 
fWriteStat = WriteFile(m_hComFile, ComSend, dwBytesToWrite, &dwBytesWritten, NULL); 
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;
k=0;
while(lpBuffer[0]!=10)
{
 k++;
// fReadStat = ReadFile(m_hComFile,lpBuffer,dwLength, &dwBytesRead,&overread);
 fReadStat = ReadFile(m_hComFile,lpBuffer,dwLength, &dwBytesRead, NULL);
 if (!fReadStat){
 if (GetLastError() == ERROR_IO_PENDING)
 {
// MessageBox(NULL,"未接收到数据,请加大延时时间","错误信息",MB_OK); 
 } 
 }
 if(k>40) 
 {
 MessageBox(NULL,"","仪表通信错误!",MB_OK);
 return 1;
 }
 if(dwBytesRead>0)
 {
 lpBuffer[1]=0;
 strcat(ComRecceive,lpBuffer);
 }
 else
 {
// MessageBox(NULL,ComRecceive,"接收数据错误!",MB_OK);
 return 1;
 }
}
// 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, n1, n2;
 
 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';
// n1=yb_tx(id, yb_id, yb_out,200);
// if(n1==1) 
// {
//  MessageBox(NULL,"" ,"读仪表数据000",MB_OK);
//  return 1;
// }
 n2=yb_tx(id, yb_send, yb_out,200);
 if(n2==1)

⌨️ 快捷键说明

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