上位机与下位机CAN-bus通信源代码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "stdafx.h"
//***************************************************************************************
extern PGLOBALCOMM g_pGlobalComm; //实时通讯进程共享数据结构
extern LONG g_lConnect;
extern LONG g_lRangeCode; //本机管理电解槽的区代码
extern LONG g_lSerialID; //本机管理电解槽的系列ID
extern LONG g_lReadNumb; //工艺数据通讯地址配置个数
extern PREADADDR g_pReadSets; //工艺数据通讯地址配置信息
extern LONG g_lCellCount; //本上位机管理的电解槽总数
extern PREALCALC g_pRealCalc; //保存实时显示数据的内存指针
extern SETPARAM g_uSetParam;
extern BYTE g_bFlagReadAll[6]; //上传所有报文时的标志值
extern LONG g_lFaultNumb; //故障信息缓冲区能容纳的故障总数
extern PREALFAULT g_pRealFault; //故障信息缓冲区首指针
extern BYTE bReadReportNo[48]; //各个上传标志位对应的上传报文号
extern BYTE bWriteReportNo[48]; //各个下传标志位对应的下传报文号
extern BYTE g_bSerialFault[80]; //各个代码的故障设置状态:0=未设置,1=普通故障,2=系列故障
extern LONG g_lReportNumb; //读系列参数的报文数
extern BYTE g_bSerialReportNo[10]; //读系列参数的报文号
extern SOCKDATA g_uRealComm; //实时通讯使用的数据
extern SOCKDATA g_uRealSerial; //读系列参数通讯使用的数据
extern TCHAR g_szCellFail[];
extern TCHAR g_szSeriFail[];
DWORD ThreadRealComm(LPVOID pParam);
void StopSocketConnect(PSOCKDATA pSockData);
//DWORD ReadSecondCurrentTime();
#define ReadSecondCurrentTime() GetSecondCurrentTime()
//*************************************************************************************************
//功能:字节数组为十六进制字符串形式的表示
//参数:pOutBuffer=输出缓冲区, pInBuffer=输入缓冲区, dwBytes=要转换的字节数
LONG TranBytesToHexStr(LPTSTR pOutBuffer, LPBYTE pInBuffer, DWORD dwBytes, DWORD dwCRLF)
{
DWORD i;
LPTSTR pOutPtr = pOutBuffer;
for (i = 1; i <= dwBytes; i++)
{
*pOutPtr = (TCHAR)(*pInBuffer >> 4) | 0x30;
if (*pOutPtr > 0x39) *pOutPtr += 7;
pOutPtr++;
*pOutPtr = (TCHAR)(*pInBuffer & 0x0f) | 0x30;
if (*pOutPtr > 0x39) *pOutPtr += 7;
pOutPtr++;
pInBuffer++;
if (dwCRLF != 0 && (i % dwCRLF) == 0)
{ *pOutPtr++ = 13;
*pOutPtr++ = 10;
} else
*pOutPtr++ = 0x20;
}
*pOutPtr = 0;
return (pOutPtr - pOutBuffer);
}
//功能:保存调试信息到数据库中
//参数:lSendCount=-1指示pReportPtr是调试信息文本,≥0指示pReportPtr是报文数据,并表示报文是第几次发送
// dwCellCode=电解槽号, ReportNo=报文号, blSend=是否为发报文
LONG SaveDebugInfo(LONG lSendCount, DWORD dwCellCode, LPBYTE pReportPtr, BOOL blSend)
{
DWORD dwIndex;
TCHAR szTemp[300];
dwIndex = sprintf(szTemp, "Insert Into DebugText (CellCode, SendCount, ReportNo, DebugOut) Values (%d,", dwCellCode
);
if (lSendCount >= 0)
{
dwIndex += sprintf(szTemp + dwIndex, "%d, %d, '%s ", lSendCount, *(pReportPtr + 6), (blSend) ? "发" : "收");
dwIndex += TranBytesToHexStr(szTemp + dwIndex, pReportPtr, g_pGlobalComm->lRptDataLen, 0);
dwIndex += sprintf(szTemp + dwIndex, "')" );
} else
{
dwIndex += sprintf(szTemp + dwIndex, "0, -1, '%s')", (LPTSTR)pReportPtr);
}
return DataExecuteStatement(g_lConnect, szTemp, adCmdText);
}
//*********************************************************************************************************
//功能:读出指定区的电解槽总数
//参数:lConnect=数据库连接句柄,lRangeCode=指定区的代码
LONG LoadRangeCellCount(LONG lConnect, LONG lRangeCode)
{
LONG lRetVal, lRangeID;
CString szTemp;
//读出本机管理的电解槽区ID
szTemp.Format("Select RecordID From CellRange Where RangeCode = %d", lRangeCode);
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lRangeID)) != ACCESS_SUCCESS)
return lRetVal;
//读本机管理的电解槽数目
szTemp.Format("SELECT Count(*) As CellNumer FROM CellDevice WHERE Parents = %d", lRangeID);
lRetVal = DataReadFieldInt(lConnect, szTemp, &g_lCellCount);
return lRetVal;
}
//功能:装入通讯参数和固定参数
//注释:填充全局变量g_lSerialID
LONG LoadCommParam(LONG lConnect)
{
LONG lRetVal;
LONG lCraftCode, lCraftValue;
TCHAR szTemp[100];
g_pGlobalComm->lCalcMinute = 1;
g_pGlobalComm->lReadCycle = 1000;
g_pGlobalComm->dwRptWaitTime = 600;
g_pGlobalComm->lRepeatCount = 2;
g_pGlobalComm->lQuerySleep = 30;
g_pGlobalComm->lDebugFlags = DEBUG_FLAG_SAVE_WRITEFLAG | DEBUG_FLAG_SAVE_WRITEDATA | DEBUG_FLAG_SHOW_COMMTIME;
g_pGlobalComm->lReportFormat = 0;
g_pGlobalComm->lRptDataLen = 13;
g_pGlobalComm->lMaxNoRetNumb = 4;
g_pGlobalComm->lCommFailNumb = 5;
g_pGlobalComm->lSaveRetry = 2;
//读出管理区的系列ID
sprintf(szTemp, "Select Parents From CellRange Where RangeCode = %d", g_lRangeCode);
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &g_lSerialID)) != ACCESS_SUCCESS)
return lRetVal;
//每次抬母线的抬升距离(0.1mm)
sprintf(szTemp, "SELECT ParamValue FROM UserParam WHERE ParamCode = 12");
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &g_uSetParam.lRaiseOff)) != ACCESS_SUCCESS)
g_uSetParam.lRaiseOff = 4000;
//阳极升降移动速度(0.1mm/s)
sprintf(szTemp, "SELECT ParamValue FROM UserParam WHERE ParamCode = 13");
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &g_uSetParam.lMoveSpeed)) != ACCESS_SUCCESS)
g_uSetParam.lMoveSpeed = 5;
//下料器氧化铝容量(原来单位0.1公斤)
sprintf(szTemp, "SELECT ParamValue FROM UserParam WHERE ParamCode = 14");
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lCraftCode)) != ACCESS_SUCCESS) lCraftCode = 160;
sprintf(szTemp, "SELECT DesignValue FROM CellDesign WHERE DesignCode = %d And SerialID = %d", lCraftCode, g_lSerialID);
if ((lRetVal = DataReadFiel
dInt(lConnect, szTemp, &lCraftValue)) != ACCESS_SUCCESS) lCraftValue = 18;
g_uSetParam.fStuffVal = (FLOAT)lCraftValue / 10;
//下料器氟化盐容量(原来单位0.1公斤)
sprintf(szTemp, "SELECT ParamValue FROM UserParam WHERE ParamCode = 15");
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lCraftCode)) != ACCESS_SUCCESS) lCraftCode = 161;
sprintf(szTemp, "SELECT DesignValue FROM CellDesign WHERE DesignCode = %d And SerialID = %d", lCraftCode, g_lSerialID);
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lCraftValue)) != ACCESS_SUCCESS) lCraftValue = 18;
g_uSetParam.fFluorine = (FLOAT)lCraftValue / 10;
return 0;
}
//功能:装入读工艺数据的地址设置信息
//参数:lConnect=数据库连接句柄
//返回:成功返回零,失败返回错误码
LONG LoadReadDataAddr(LONG lConnect)
{
LONG lIndex;
LONG lRetVal;
RECORDINFO uRecordInfo;
PFIELDDATA pFieldData;
PREADADDR pReadSets;
TCHAR szTemp[] = "Select CraftCode, ReadAddr, ReadBit, DataType, WriteAddr, ReadFlag From CraftParam Where ReadAddr >= 6000 And ReadAddr < 6900 Order By CraftCode Desc";
//打开记录集
uRecordInfo.dwCmdType = adCmdText;
uRecordInfo.pDataBuf = NULL;
if ((lRetVal = DataOpenReadRec(lConnect, szTemp, &uRecordInfo)) == ACCESS_SUCCESS)
{
pFieldData = (PFIELDDATA)uRecordInfo.pDataBuf;
if (uRecordInfo.dwRecCount > 0)
{ //申请缓冲区: 工艺代码从0开始
g_lReadNumb = pFieldData->lValue + 1; //取出设置的最大编号
g_pReadSets = (PREADADDR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(READADDR) * g_lReadNumb);
if (g_pReadSets != NULL)
{ //预置所有的写地址为-1,当写地址小于零时表示没有对应的写报文。
for (lIndex = 0; lIndex < g_lReadNumb; lIndex++)
{
(g_pReadSets + lIndex)->lWriteAddr = -1;
(g_pReadSets + lIndex)->lReadAddr = -1;
}
//生成读数据地址设置信息数据
for (lIndex = 0; lIndex < (LONG)uRecordInfo.dwRecCount; lIndex++)
{
//读系列参数增加****
if (pFieldData->lValue == Code_Currunt)
g_bSerialReportNo[g_lReportNumb++] = ((pFieldData + 1)->lValue - 6000) / REPORT_CELL_NUMB;
if (pFieldData->lValue == Code_SerialVolt)
g_bSerialReportNo[g_lReportNumb++] = ((pFieldData + 1)->lValue - 6000) / REPORT_CELL_NUMB;
//保存读写地址信息参数
pReadSets = g_pReadSets + pFieldData++->lValue; //根据CraftCode确定位置
pReadSets->lReadAddr = pFieldData++->lValue - 6000; //ReadAddr
pReadSets->wReadBit = pFieldData++->iValue; //ReadBit
pReadSets->wDataType = pFieldData++->iValue; //DataType
pReadSets->lWriteAddr = pFieldData++->lValue - 6000; //WriteAddr
pReadSets->wReadFlag = pFieldData++->iValue; //ReadFlag
//生成上传报文号与上传标志对照表、上传所有报文时的标志值
if (pReadSets->wReadFlag >= 0 && pReadSets->wReadFlag < 48)
{
bReadReportNo[pRea
dSets->wReadFlag] = (BYTE)(pReadSets->lReadAddr / REPORT_CELL_NUMB);
g_bFlagReadAll[pReadSets->wReadFlag / 8] |= (1 << (pReadSets->wReadFlag % 8));
}
}
} else
lRetVal = ACCESS_ERR_INSUFFICIENT_MEMORY;
}
//释放缓冲区
DataFreeRecord(&uRecordInfo);
}
return lRetVal;
}
//功能:读入电解槽数据信息
//参数:lConnect=数据库连接句柄
LONG LoadCellDevAddr(LONG lConnect)
{
LONG lRetVal, lRangeID;
DWORD dwIdx, dwRealTime;
RECORDINFO uRecordInfo;
PFIELDDATA pFieldData;
PREALCALC pRealCalc;
TCHAR szTemp[200];
//读出本管理区的ID
sprintf(szTemp, "SELECT RecordID FROM CellRange WHERE RangeCode = %d", g_lRangeCode);
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lRangeID)) != ACCESS_SUCCESS)
return lRetVal;
//打开并读出电解槽数据表
sprintf(szTemp, "Select CellCode, CellAddr, CommSet From CellDevice Where Parents = %d Order By CellCode", lRangeID);
uRecordInfo.dwCmdType = adCmdText;
uRecordInfo.pDataBuf = NULL;
if ((lRetVal = DataOpenReadRec(lConnect, szTemp, &uRecordInfo)) != ACCESS_SUCCESS)
return lRetVal;
//填充相关数据
pFieldData = (PFIELDDATA)uRecordInfo.pDataBuf;
pRealCalc = g_pRealCalc;
dwRealTime = ReadSecondCurrentTime();
for (dwIdx = 1; dwIdx <= uRecordInfo.dwRecCount; dwIdx++, pRealCalc++)
{
pRealCalc->dwCellCode = pFieldData++->lValue;
pRealCalc->bPlcAddr = pFieldData++->bValue;
pRealCalc->bCommState = (pFieldData++->bValue == 0) ? COMM_STATE_NORMAL : COMM_STATE_DISABLE;
pRealCalc->lCellIdx = dwIdx - 1;
pRealCalc->dwRealTime = dwRealTime;
}
//释放缓冲区
DataFreeRecord(&uRecordInfo);
return lRetVal;
}
//功能:读出下传报文号与下传标志对照
//参数:lConnect=数据库连接句柄
//返回:成功返回零,失败返回错误码
LONG LoadWriteAddrInfo(LONG lConnect)
{
LONG lRetVal, lFlagAddr;
DWORD dwIndex;
RECORDINFO uRecordInfo;
PFIELDDATA pFieldData;
TCHAR szTemp[] = "Select WriteAddr, WriteFlag From CraftParam Where WriteAddr >= 6000 And WriteAddr < 6900";
//打开记录集
uRecordInfo.dwCmdType = adCmdText;
uRecordInfo.pDataBuf = NULL;
if ((lRetVal = DataOpenReadRec(lConnect, szTemp, &uRecordInfo)) == ACCESS_SUCCESS)
{
pFieldData = (PFIELDDATA)uRecordInfo.pDataBuf;
for (dwIndex = 0; dwIndex < uRecordInfo.dwRecCount; dwIndex++)
{
lFlagAddr = (pFieldData + 1)->lValue;
if (lFlagAddr < 48)
bWriteReportNo[lFlagAddr] = (BYTE)((pFieldData->lValue - 6000)/ REPORT_CELL_NUMB);
pFieldData += 2;
}
//释放缓冲区
DataFreeRecord(&uRecordInfo);
}
return lRetVal;
}
//功能:读出所有的电解槽设计参数到通讯缓冲区
LONG LoadDesignParam(LONG lConnect)
{
LONG lRetVal, lIndex;
DWORD dwIndex;
PREALCALC pRealCalc;
RECORDINFO uRecordInfo;
PFIELDDATA pFieldData;
CString szTemp;
szTemp.Format("Select CellDesign.DesignCode, CraftParam.WriteAddr, CellDesign.
DesignValue From CellDesign Inner Join CraftParam \
On CellDesign.DesignCode = CraftParam.CraftCode Where WriteAddr >= 6000 And WriteAddr < 6900 And CellDesign.SerialId = %d", g_lSerialID);
uRecordInfo.dwCmdType = adCmdText;
uRecordInfo.pDataBuf = NULL;
if ((lRetVal = DataOpenReadRec(lConnect, (LPTSTR)(LPCTSTR)szTemp, &uRecordInfo)) == ACCESS_SUCCESS)
{
pFieldData = (PFIELDDATA)uRecordInfo.pDataBuf;
for (dwIndex = 0; dwIndex < uRecordInfo.dwRecCount; dwIndex++)
{ //存入每个电解槽的通讯数据缓冲区中
pRealCalc = g_pRealCalc;
for (lIndex = 0; lIndex < g_lCellCount; lIndex++, pRealCalc++)
pRealCalc->wDataBuf[(pFieldData + 1)->lValue - 6000] = (pFieldData + 2)->iValue;
pFieldData += 3;
}
//释放缓冲区
DataFreeRecord(&uRecordInfo);
}
return lRetVal;
}
//功能:读出所有电解槽的下传参数的最后一次的值
LONG LoadDefineParam(LONG lConnect, PREALCALC pRealCalc, LONG lCellCount)
{
LONG lCraftCode;
LONG lRetVal, lIndex;
DWORD dwIndex;
LPWORD pwReadPtr, pwWritePtr;
RECORDINFO uRecordInfo;
PFIELDDATA pFieldData;
PREADADDR pAddrSets;
CString szTemp;
//对所有的电解槽循环
for (lIndex = 0; lIndex < lCellCount; lIndex++, pRealCalc++)
{
szTemp.Format("SELECT CraftCode, CraftValue FROM CraftValue WHERE CellCode = %d ORDER BY CraftCode, RealTime DESC", pRealCalc->dwCellCode);
uRecordInfo.dwCmdType = adCmdText;
uRecordInfo.pDataBuf = NULL;
if ((lRetVal = DataOpenReadRec(lConnect, (LPTSTR)(LPCTSTR)szTemp, &uRecordInfo)) == ACCESS_SUCCESS)
{
pFieldData = (PFIELDDATA)uRecordInfo.pDataBuf;
lCraftCode = 0;
for (dwIndex = 0; dwIndex < uRecordInfo.dwRecCount; dwIndex++, pFieldData += uRecordInfo.dwFieldCount)
if (pFieldData->lValue != lCraftCode && pFieldData->lValue < g_lReadNumb)
{
lCraftCode = pFieldData->lValue;
pAddrSets = g_pReadSets + lCraftCode;
if (pAddrSets->lReadAddr >= 0)
{
pwReadPtr = pRealCalc->wDataBuf + pAddrSets->lReadAddr;
pwWritePtr = pRealCalc->wDataBuf + pAddrSets->lWriteAddr;
switch (pAddrSets->wDataType) {
case 0: //是位值
if ((pFieldData + 1)->lValue != 0)
{
*pwReadPtr |= (1 << pAddrSets->wReadBit);
if (pAddrSets->lWriteAddr >= 0)
*pwWritePtr |= (1 << pAddrSets->wWriteBit);
}
break;
case 3:
*((LPLONG)pwReadPtr) = (pFieldData + 1)->lValue;
if (pAddrSets->lWriteAddr >= 0)
*((LPLONG)pwWritePtr) = (pFieldData + 1)->lValue;
break;
default:
*pwReadPtr = (pFieldData + 1)->wValue;
if (pAddrSets->lWriteAddr >= 0)
*pwWritePtr = (pFieldData + 1)->wValue;
break;
}
}
}
//释放缓冲区
DataFreeRecord(&uRecordInfo);
}
}
return lRetVal;
}
//功能:读入最后一次分钟数据的计算时间
//参数:lConnect=数据库连接句柄
LONG LoadLastMinuteTime(LONG lConnect)
{
LONG lRetVal, lIndex;
LONG lMinuteTime;
PREALCALC pRealCalc;
TCHAR szTemp[150];
if ((pRealCalc = g_pRealCalc) != NULL)
for (lIndex = 0; lIndex < g_lCellCount; lIndex++, pRealCalc++)
{
sprintf(szTemp, "Select Max(RealTime) From RealMinute%d", pRealCalc->dwCellCode);
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lMinuteTime)) == ACCESS_SUCCESS && lMinuteTime > 0)
pRealCalc->lMinuteLast = lMinuteTime + 60;
else
{ //读电解槽的启动时间
sprintf(szTemp, "Select Min(RealTime) From RealData%d Where RealTime > 0", pRealCalc->dwCellCode);
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lMinuteTime)) == ACCESS_SUCCESS && lMinuteTime > 0)
pRealCalc->lMinuteLast = (lMinuteTime / 60) * 60;
}
}
return lRetVal;
}
//功能:读入报表数据采集最后一次计算的时间段
//参数:lConnect=数据库连接句柄
//LONG LoadCalcTimeSection(LONG lConnect)
//{
// LONG lRetVal, lIndex;
// LONG lCalcTime;
// PREALCALC pRealCalc;
// TCHAR szTemp[150];
//
// if ((pRealCalc = g_pRealCalc) != NULL)
// for (lIndex = 0; lIndex < g_lCellCount; lIndex++, pRealCalc++)
// {
// sprintf(szTemp, "Select Max(RealTime) AS MaxTime From RealCalc WHERE CellCode = %d", pRealCalc->dwCellCode);
// if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lCalcTime)) == ACCESS_SUCCESS && lCalcTime > 0)
// pRealCalc->uRealReport.lCalcLast = lCalcTime + CALC_TIME_SECTION;
// else
// { //读电解槽的启动时间
// sprintf(szTemp, "Select Min(RealTime) AS MinTime From RealData%d Where RealTime > 0", pRealCalc->dwCellCode);
// if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lCalcTime)) == ACCESS_SUCCESS && lCalcTime > 0)
// pRealCalc->uRealReport.lCalcLast = (lCalcTime / CALC_TIME_SECTION) * CALC_TIME_SECTION;
// }
// }
// return lRetVal;
//}
//功能:读入数据库中最后一次的效应时间,以便计算效应间隔时使用
//参数:lConnect=数据库连接句柄
//注释:初始化结构REALCALC中的成员dwELastTime
LONG LoadLastEffectTime(LONG lConnect)
{
LONG lRetVal, lIndex;
LONG lRealTime;
PREALCALC pRealCalc;
TCHAR szTemp[150];
//读数据记录并填充相关数据
if ((pRealCalc = g_pRealCalc) != NULL)
for (lIndex = 0; lIndex < g_lCellCount; lIndex++, pRealCalc++)
{
sprintf(szTemp, "Select Top 1 RealTime From RealEffect Where CellCode = %d And SustainTime <> 0 Order By RealTime Desc", pRealCalc->dwCellCode);
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lRealTime)) == ACCESS_SUCCESS && lRealTime > 0)
{ //读出成功, 保存它
pRealCalc->lELastTime = lRealTime;
} else
{ //没有找到,以槽的启动时间作为初始值
sprintf(szTemp, "Select SetupDays From CellDevice Where CellCode = %d", pRealCalc->dwCellCode);
if ((lRetVal = DataReadFieldInt(lConnect, szTemp, &lRealTime)) == ACCESS_SUCCESS && lRealTime > 0)
{ //读出成功,将启动日期的天数转换为相对秒数
pR
ealCalc->lELastTime = GetSecondFromOleTime((DOUBLE)lRealTime);
}
}
}
return ACCESS_SUCCESS;
}
//功能:读出所有系列故障的故障码
//参数:lConnect=数据库连接句柄
//注释:初始化g_bSerialFault
LONG LoadSerialFault(LONG lConnect)
{
LONG lRetVal;
DWORD dwIndex;
RECORDINFO uRecordInfo;
PFIELDDATA pFieldData;
TCHAR szTemp[] = "SELECT FaultCode, FaultSerial FROM FaultList WHERE FaultCode < 80";
//读数据记录并填充相关数据
ZeroMemory(g_bSerialFault, 80);
uRecordInfo.dwCmdType = adCmdText;
uRecordInfo.pDataBuf = NULL;
if ((lRetVal = DataOpenReadRec(lConnect, szTemp, &uRecordInfo)) == ACCESS_SUCCESS)
{
pFieldData = (PFIELDDATA)uRecordInfo.pDataBuf;
for (dwIndex = 0; dwIndex < uRecordInfo.dwRecCount; dwIndex++)
{
g_bSerialFault[pFieldData->lValue] = 1;
if ((pFieldData + 1)->bValue != 0)
g_bSerialFault[pFieldData->lValue] = 2;
pFieldData += 2;
}
//释放缓冲区
DataFreeRecord(&uRecordInfo);
}
return lRetVal;
}
//**********************************初始化程序***********************************
//功能:读入通讯配置参数
VOID LoadCommConfig(LPTSTR pszConfigFile)
{
ZeroMemory(&g_uRealComm, sizeof(SOCKDATA));
g_uRealComm.lTimerID = TIMTER_CONNECT_ID;
g_uRealComm.lFailCode = FAULT_NET_COMM_FAILURE;
g_uRealComm.pszFailPrompt = g_szCellFail;
ZeroMemory(&g_uRealSerial, sizeof(SOCKDATA));
g_uRealSerial.lTimerID = TIMTER_SERIALS_ID;
g_uRealSerial.lFailCode = FAULT_NET_SERIAL_FAILURE;
g_uRealSerial.pszFailPrompt = g_szSeriFail;
//读入本机管理的区信息
g_lRangeCode = ::GetPrivateProfileInt("CommInfomation", "RangeCode", 0, pszConfigFile);
g_uRealComm.lCommPort = ::GetPrivateProfileInt("CommInfomation", "CommPort", 0, pszConfigFile);
::GetPrivateProfileString("CommInfomation", "CommAddr", "", g_uRealComm.szCommAddr, sizeof(g_uRealComm.szCommAddr), pszConfigFile);
//读入上传系列参数的连接信息
g_uRealSerial.lCommPort = ::GetPrivateProfileInt("CommInfomation", "SerialPort", 0, pszConfigFile);
::GetPrivateProfileString("CommInfomation", "SerialAddr", "", g_uRealSerial.szCommAddr, sizeof(g_uRealSerial.szCommAddr), pszConfigFile);
}
//功能:实时通讯初始化
//参数:lConnect=数据库连接句柄
LONG RealCommIntialize(LONG lConnect, HWND hInfoWnd)
{
LONG lRetVal;
//删除原来的调试数据
//lRetVal = DataExecuteStatement(lConnect, "TRUNCATE TABLE DebugText", adCmdText);
//装入通讯参数和和电解槽的下料容器参数
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"正在读下料容器参数.....");
if ((lRetVal = LoadCommParam(lConnect)) != ACCESS_SUCCESS)
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"读下料容器参数失败!!");
//装入工艺数据的地址设置信息
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"正在读工艺
数据的地址设置信息.....");
if ((lRetVal = LoadReadDataAddr(lConnect)) == ACCESS_SUCCESS)
lRetVal = LoadWriteAddrInfo(lConnect);
if (lRetVal != ACCESS_SUCCESS)
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"读工艺数据的地址设置信息失败!!");
if (g_lRangeCode != 0 && g_uRealComm.lCommPort != 0)
{
//读入电解槽PLC地址信息并初始化结构
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"正在读入电解槽设置信息.....");
if ((lRetVal = LoadCellDevAddr(lConnect)) != ACCESS_SUCCESS)
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_ERROR, (LPARAM)(LPTSTR)"读入电解槽信息设置失败!!");
//读入分钟数据信息
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"正在读入读入分钟数据信息.....");
//if ((lRetVal = LoadCalcTimeSection(lConnect)) != ACCESS_SUCCESS)
// ::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_ERROR, (LPARAM)(LPTSTR)"读入统计时间段信息失败!!");
if ((lRetVal = LoadLastMinuteTime(lConnect)) != ACCESS_SUCCESS)
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_ERROR, (LPARAM)(LPTSTR)"读入读入分钟数据信息失败!!");
//读入最后一次的效应时间
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"正在读入最后一次效应时间.....");
if ((lRetVal = LoadLastEffectTime(lConnect)) != ACCESS_SUCCESS)
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_ERROR, (LPARAM)(LPTSTR)"读入最后一次效应时间失败!!");
//读出电解槽设计参数到通讯缓冲区
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"正在读入电解槽设计参数值.....");
if ((lRetVal = LoadDesignParam(lConnect)) != ACCESS_SUCCESS)
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"读入电解槽设计参数值失败!!!");
//读出电解槽最后一次的设定参数值
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"正在读入电解槽最后一次的设定参数值.....");
if ((lRetVal = LoadDefineParam(lConnect, g_pRealCalc, g_lCellCount)) != ACCESS_SUCCESS)
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"读入电解槽最后一次的设定参数值失败!!!");
//读入故障设置情况
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"正在读入故障设置信息.....");
if ((lRetVal = LoadSerialFault(lConnect)) != ACCESS_SUCCESS)
::SendMessage(hInfoWnd, PROMPT_SHOW_INFO, INFO_TYPE_PROMPT, (LPARAM)(LPTSTR)"读入故障设置信息失败!!!.....");
//创建本机管理区通讯线程
g_uRealComm.hCommEvents = CreateEvent(NULL,TRUE, FALSE, NULL); //启动查询事件: 无安全属性、人工复位、初始无信号、无名称
if (g_uRealComm.hCommEvents != NULL)
{
g_uRealComm.hCommThread = CreateTh
read(NULL,0, LPTHREAD_START_ROUTINE(ThreadRealComm), NULL, 0, NULL);
SetThreadPriority(g_uRealComm.hCommThread, THREAD_PRIORITY_HIGHEST); //设置为较高的优先级
}
if ((g_pRealFault = (PREALFAULT)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(REALFAULT) * g_lCellCount * 5)) != NULL)
g_lFaultNumb = g_lCellCount * 5; //故障信息缓冲区能容纳的故障总数
}
//创建实时通讯的线程
return 0;
}
//功能:实时通讯反初始化
void UnRealCommIntialize()
{
//停止槽控机数据采集线程
if (g_uRealComm.hCommEvents != NULL)
{
//g_uRealComm.blEnableComm = FALSE;
SetEvent(g_uRealComm.hCommEvents);
WaitThreadStop(g_uRealComm.hCommThread);
CloseHandle(g_uRealComm.hCommEvents);
}
//停止系列参数采集线程
if (g_uRealSerial.hCommEvents != NULL)
{
//g_uRealSerial.blEnableComm = FALSE;
SetEvent(g_uRealSerial.hCommEvents);
WaitThreadStop(g_uRealSerial.hCommThread);
CloseHandle(g_uRealSerial.hCommEvents);
}
//停止通讯套接字
StopSocketConnect(&g_uRealComm);
StopSocketConnect(&g_uRealSerial);
//释放数据缓冲区
if (g_pReadSets != NULL)
g_pReadSets = (PREADADDR)GlobalFree(g_pReadSets);
}