#include "host_modbus_rtu.h" /////////////////////////////////////////////////////////////////////////////////// //Valid slave device addresses are in the range of 0 ? 247 decimal. // //The individual slave devices are assigned addresses in the range of 1 ? 247. // //Address 0 is used for the broadcast address, which all slave devices recognize.// // 在 RTU 模式,报文帧由时长至少为3.5 个字符时间的空闲间隔区分。 // 假如通信波特率为 19200,那么: // 1.5 个字符间隔 = 1/19200 *11*1.5*1000=0.86ms // 3.5 个字符间隔 = 1/19200 *11*3.5*1000=2ms // 在通信速率等于或低于19200 Bps 时,这两个定时必须严格遵守; // 对于波特率大于19200 Bps 的情形,应该使用2 个定时的固定值:建议的字符间超时时间(t1.5)为750μs,帧间的超时时间(t1.5) 为1.750ms。 ///////////////////////////////////////////////////////////////////////////////// CHostModbusRtuProcessItem::CHostModbusRtuProcessItem() { m_nFramePoll = 0; m_nPollCount = -1; m_nCurFrame = 0; memset(m_nModbusFrames, 0, sizeof(m_nModbusFrames)); } CHostModbusRtuProcessItem::~CHostModbusRtuProcessItem() { m_nFramePoll = 0; m_nPollCount = -1; m_nCurFrame = 0; memset(m_nModbusFrames, 0, sizeof(m_nModbusFrames)); } void CHostModbusRtuProcessItem::AddFrames(struModbusExtFrame* yxs, struModbusExtFrame* ycs, struModbusExtFrame* yms) { int i = 0, j = 0; memset(m_nModbusFrames, 0, sizeof(m_nModbusFrames)); for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (yxs[j].FrameType == 0 || yxs[j].FuncCode == 0 || yxs[j].RegCount == 0) continue; memcpy(&m_nModbusFrames[i], &yxs[j], sizeof(struModbusExtFrame)); i++; if (i >= MODBUS_RTU_AUTOMATIC_FRAME_MAX) break; } for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (ycs[j].FrameType == 0 || ycs[j].FuncCode == 0 || ycs[j].RegCount == 0) continue; memcpy(&m_nModbusFrames[i], &ycs[j], sizeof(struModbusExtFrame)); i++; if (i >= MODBUS_RTU_AUTOMATIC_FRAME_MAX) break; } for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (yms[j].FrameType == 0 || yms[j].FuncCode == 0 || yms[j].RegCount == 0) continue; memcpy(&m_nModbusFrames[i], &yms[j], sizeof(struModbusExtFrame)); i++; if (i >= MODBUS_RTU_AUTOMATIC_FRAME_MAX) break; } } struModbusExtFrame* CHostModbusRtuProcessItem::GetNextFrame(void) { int last; if (m_nCurFrame >= MODBUS_RTU_AUTOMATIC_FRAME_MAX) return NULL; if (m_nCurFrame < 0) m_nCurFrame = -1; last = m_nCurFrame; for (m_nCurFrame++; m_nCurFrame < MODBUS_RTU_AUTOMATIC_FRAME_MAX; m_nCurFrame++) { if (m_nModbusFrames[m_nCurFrame].FuncCode == 0 || m_nModbusFrames[m_nCurFrame].FrameType == 0) break; return &m_nModbusFrames[m_nCurFrame]; } for (m_nCurFrame = 0; m_nCurFrame <= last; m_nCurFrame++) { if (m_nModbusFrames[m_nCurFrame].FuncCode == 0 || m_nModbusFrames[m_nCurFrame].FrameType == 0) break; return &m_nModbusFrames[m_nCurFrame]; } return NULL; } void CHostModbusRtuProcessItem::Attach(int uid, int physicsAddress /* = 0 */, int commonAddress /* = 0 */, int originatorAddress /* = 0 */) { CPortProcessItem::Attach(uid, physicsAddress); m_nFramePoll = 0; m_nPollCount = -1; m_nCurFrame = 0; memset(m_nModbusFrames, 0, sizeof(m_nModbusFrames)); } void CHostModbusRtuProcessItem::Release(void) { m_nFramePoll = 0; m_nPollCount = -1; m_nCurFrame = 0; memset(m_nModbusFrames, 0, sizeof(m_nModbusFrames)); CPortProcessItem::Release(); } CHostModbusRtuProcess::CHostModbusRtuProcess() { m_nNeedCount = 2; m_nState = MODBUSS_SYNC; m_nCount = 0; m_nFrameCount = 0; m_nCurFrame = 0; m_nSendPoint = 0; m_nCurBeginReg = 0; m_nNeedSend = FALSE; m_nFramePoll = 0; } CHostModbusRtuProcess::~CHostModbusRtuProcess() { } CPortProcessItem *CHostModbusRtuProcess::CreateItem(int ord) { return dynamic_cast(new CHostModbusRtuProcessItem); } void CHostModbusRtuProcess::DestroyItem(int ord, BOOLEAN bDeleted /* = FALSE */) { CHostModbusRtuProcessItem *pItem = (CHostModbusRtuProcessItem *)GetItem(ord); if (pItem != NULL && !bDeleted) { delete pItem; return CPortProcess::DestroyItem(ord, TRUE); } return CPortProcess::DestroyItem(ord, bDeleted); } void CHostModbusRtuProcess::sort1(STRUCT_PARAM *params, int count) { int i, j, n; STRUCT_PARAM temp; n = count; for (i = 0; i < n - 1; ++i) { //比较n-1轮 for (j = 0; j < n - 1 - i; ++j) { //每轮比较n-1-i次, if (params[j].param[0] > params[j + 1].param[0]) { memcpy(&temp, ¶ms[j], sizeof(STRUCT_PARAM)); memcpy(¶ms[j], ¶ms[j + 1], sizeof(STRUCT_PARAM)); memcpy(¶ms[j + 1], &temp, sizeof(STRUCT_PARAM)); } } } } void CHostModbusRtuProcess::sort2(STRUCT_PARAM *params, int count) { int i, j, n; STRUCT_PARAM temp; n = count; for (i = 0; i < n - 1; ++i) { //比较n-1轮 for (j = 0; j < n - 1 - i; ++j) { //每轮比较n-1-i次, int addr1 = (int)MAKEWORD(params[j].param[1], params[j].param[2]); int addr2 = (int)MAKEWORD(params[j+1].param[1], params[j+1].param[2]); if (addr1 > addr2) { memcpy(&temp, ¶ms[j], sizeof(STRUCT_PARAM)); memcpy(¶ms[j], ¶ms[j + 1], sizeof(STRUCT_PARAM)); memcpy(¶ms[j + 1], &temp, sizeof(STRUCT_PARAM)); } } } } void CHostModbusRtuProcess::calc1(void) { int i, j, n, uid; BYTE addr; CHostModbusRtuProcessItem *pItem; for (i = 0; i < PROCESS_UNIT_NUM; i++) { pItem = (CHostModbusRtuProcessItem *)GetItem(i); if (NULL == pItem) continue; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) continue; if (GetUnitAddr(uid, &addr, 1)) { //获取单元地址成功,则该段原地址采用配置地址,否则该单元为无效地址。 pItem->Attach(uid, addr); } struModbusExtFrame ycframes[MODBUS_RTU_AUTOMATIC_FRAME]; struModbusExtFrame ymframes[MODBUS_RTU_AUTOMATIC_FRAME]; struModbusExtFrame yxframes[MODBUS_RTU_AUTOMATIC_FRAME]; memset(ycframes, 0, sizeof(ycframes)); memset(ymframes, 0, sizeof(ymframes)); memset(yxframes, 0, sizeof(yxframes)); struUnitModbusOption option; if (GetUnitOption(uid, &option, sizeof(option))) { if (option.use_owner_config) { //采用协议配置 if (option.modbus.yx1Enable) { yxframes[0].FrameType = MODBUSP_READ_YX1; yxframes[0].FuncCode = option.modbus.yx1FuncCode; yxframes[0].RegBegin = option.modbus.yx1Begin; yxframes[0].RegCount = option.modbus.yx1Count; } if (option.modbus.yx2Enable) { yxframes[1].FrameType = MODBUSP_READ_YX1; yxframes[1].FuncCode = option.modbus.yx2FuncCode; yxframes[1].RegBegin = option.modbus.yx2Begin; yxframes[1].RegCount = option.modbus.yx2Count; } if (option.modbus.yc1Enable) { ycframes[0].FrameType = MODBUSP_READ_YC1; ycframes[0].FuncCode = option.modbus.yc1FuncCode; ycframes[0].RegBegin = option.modbus.yc1Begin; ycframes[0].RegCount = option.modbus.yc1Count; } if (option.modbus.yc2Enable) { ycframes[1].FrameType = MODBUSP_READ_YC1; ycframes[1].FuncCode = option.modbus.yc2FuncCode; ycframes[1].RegBegin = option.modbus.yc2Begin; ycframes[1].RegCount = option.modbus.yc2Count; } if (option.modbus.yc3Enable) { ycframes[2].FrameType = MODBUSP_READ_YC1; ycframes[2].FuncCode = option.modbus.yc3FuncCode; ycframes[2].RegBegin = option.modbus.yc3Begin; ycframes[2].RegCount = option.modbus.yc3Count; } if (option.modbus.yc4Enable) { ycframes[3].FrameType = MODBUSP_READ_YC1; ycframes[3].FuncCode = option.modbus.yc4FuncCode; ycframes[3].RegBegin = option.modbus.yc4Begin; ycframes[3].RegCount = option.modbus.yc4Count; } if (option.modbus.ym1Enable) { ymframes[0].FrameType = MODBUSP_READ_YM1; ymframes[0].FuncCode = option.modbus.ym1FuncCode; ymframes[0].RegBegin = option.modbus.ym1Begin; ymframes[0].RegCount = option.modbus.ym1Count; } if (option.modbus.ym2Enable) { ymframes[1].FrameType = MODBUSP_READ_YM1; ymframes[1].FuncCode = option.modbus.ym2FuncCode; ymframes[1].RegBegin = option.modbus.ym2Begin; ymframes[1].RegCount = option.modbus.ym2Count; } //按寄存器排序 pItem->AddFrames(ycframes, ymframes, yxframes); continue; } } { int yccount, ymcount, yxcount; yccount = GetUnitYCCount(uid); ymcount = GetUnitYMCount(uid); yxcount = GetUnitYXCount(uid); STRUCT_PARAM *ycparam = NULL, *ymparam = NULL, *yxparam = NULL; if (yccount) ycparam = new STRUCT_PARAM[yccount]; if (ymcount) ymparam = new STRUCT_PARAM[ymcount]; if (yxcount) yxparam = new STRUCT_PARAM[yxcount]; if (ycparam) { memset(ycparam, 0, sizeof(STRUCT_PARAM) * yccount); for (n = 0; n < yccount; n++) { memcpy(ycparam[n].param, GetUnitYCParamByPoint(uid, n), sizeof(STRUCT_PARAM)); } //按功能码排序 sort1(ycparam, yccount); //按寄存器地址排序 sort2(ycparam, yccount); //组帧 for (n = 0; n < yccount; n++) { WORD addr = MAKEWORD(ycparam[n].param[1], ycparam[n].param[2]); if (addr >= 65535) continue; for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (ycframes[j].FuncCode == 0) { ycframes[j].FrameType = MODBUSP_READ_YC1; ycframes[j].FuncCode = ycparam[n].param[0]; ycframes[j].RegBegin = addr; ycframes[j].RegCount = ycparam[n].param[3]; break; } if (ycframes[j].FuncCode == ycparam[n].param[0]) { if (addr <= MODBUS_MAX_WORD_REGISTER_NUM + ycframes[j].RegBegin) { int len = addr - ycframes[j].RegBegin; if (len) { ycframes[j].RegCount = len + ycparam[n].param[3]; } else { vLog(LOG_DEBUG, "遥测测点配置了相同的功能码和寄存器地址\n"); } break; } } } } } if (ymparam) { memset(ymparam, 0, sizeof(STRUCT_PARAM) * ymcount); for (n = 0; n < ymcount; n++) { memcpy(ymparam[n].param, GetUnitYMParamByPoint(uid, n), sizeof(STRUCT_PARAM)); } sort1(ymparam, ymcount); sort2(ymparam, ymcount); //组帧 for (n = 0; n < ymcount; n++) { WORD addr = MAKEWORD(ymparam[n].param[1], ymparam[n].param[2]); if (addr >= 65535) continue; for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (ymframes[j].FuncCode == 0) { ymframes[j].FrameType = MODBUSP_READ_YM1; ymframes[j].FuncCode = ymparam[n].param[0]; ymframes[j].RegBegin = addr; ymframes[j].RegCount = ymparam[n].param[3]; break; } if (ymframes[j].FuncCode == ymparam[n].param[0]) { if (addr <= MODBUS_MAX_WORD_REGISTER_NUM + ymframes[j].RegBegin) { int len = addr - ymframes[j].RegBegin; if (len) { ymframes[j].RegCount = len + ymparam[n].param[3]; } else { vLog(LOG_DEBUG, "遥脉测点配置了相同的功能码和寄存器地址\n"); } break; } } } } } if (yxparam) { memset(yxparam, 0, sizeof(STRUCT_PARAM) * yxcount); for (n = 0; n < yxcount; n++) { memcpy(yxparam[n].param, GetUnitYXParamByPoint(uid, n), sizeof(STRUCT_PARAM)); } sort1(yxparam, yxcount); sort2(yxparam, yxcount); //组帧 for (n = 0; n < yxcount; n++) { WORD addr = MAKEWORD(yxparam[n].param[1], yxparam[n].param[2]); if (addr >= 65535) continue; for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (yxframes[j].FuncCode == 0) { yxframes[j].FrameType = MODBUSP_READ_YX1; yxframes[j].FuncCode = yxparam[n].param[0]; yxframes[j].RegBegin = addr; yxframes[j].RegCount = 1; break; } if (yxframes[j].FuncCode == yxparam[n].param[0]) { int len = addr - yxframes[j].RegBegin; if (len) { if (yxframes[j].FuncCode == MODBUSC_F01 || yxframes[j].FuncCode == MODBUSC_F02) { if (addr <= MODBUS_MAX_BITMAP_REGISTER_NUM + yxframes[j].RegBegin) { yxframes[j].RegCount = len + 1; break; } } else if (yxframes[j].FuncCode == MODBUSC_F03 || yxframes[j].FuncCode == MODBUSC_F04) { if (addr <= MODBUS_MAX_WORD_REGISTER_NUM + yxframes[j].RegBegin) { yxframes[j].RegCount = len + 1; break; } } } else { if (yxframes[j].FuncCode == MODBUSC_F01 || yxframes[j].FuncCode == MODBUSC_F02) { vLog(LOG_DEBUG, "遥信测点配置了相同的功能码和寄存器地址\n"); } break; } } } } } //按寄存器排序 pItem->AddFrames(ycframes, ymframes, yxframes); } } } BOOLEAN CHostModbusRtuProcess::OnPreCreate(int id) { if (!CPortProcess::OnPreCreate(id)) return FALSE; m_nTimeout = GetTimeout(); calc1(); return TRUE; } BOOLEAN CHostModbusRtuProcess::Run(void) { int count; BOOLEAN bFailed; WORD checkSum; BYTE buffer[512]; if (!CPortProcess::Run()) return FALSE; ////////////////////////////////////////////////// // process recv data // ////////////////////////////////////////////////// if (m_nNeedCount < 2) m_nNeedCount = 2; if (GetDataCount() >= m_nNeedCount) { if (!GetData(buffer, m_nNeedCount)) { vLog(LOG_ERROR, "%s GetData() ERROR!\n", __FILE__); } FeedDog(); bFailed = FALSE; if (m_nState == MODBUSS_CTRL) { if (((buffer[1] & 0x7f) != MODBUSC_F01) && ((buffer[1] & 0x7f) != MODBUSC_F02) && ((buffer[1] & 0x7f) != MODBUSC_F03) && ((buffer[1] & 0x7f) != MODBUSC_F04) && ((buffer[1] & 0x7f) != MODBUSC_F05) && ((buffer[1] & 0x7f) != MODBUSC_F06) && ((buffer[1] & 0x7f) != MODBUSC_F07) && ((buffer[1] & 0x7f) != MODBUSC_F08) && ((buffer[1] & 0x7f) != MODBUSC_F11) && ((buffer[1] & 0x7f) != MODBUSC_F12) && ((buffer[1] & 0x7f) != MODBUSC_F15) && ((buffer[1] & 0x7f) != MODBUSC_F16) && ((buffer[1] & 0x7f) != MODBUSC_F17) && ((buffer[1] & 0x7f) != MODBUSC_F20) && ((buffer[1] & 0x7f) != MODBUSC_F21) && ((buffer[1] & 0x7f) != MODBUSC_F22) && ((buffer[1] & 0x7f) != MODBUSC_F23) && ((buffer[1] & 0x7f) != MODBUSC_F24) && ((buffer[1] & 0x7f) != MODBUSC_F43) && ((buffer[1] & 0x7f) != MODBUSC_F26)) { bFailed = TRUE; } else if ((buffer[1] & 0x80) == 0x80) { m_nNeedCount = (4 + 1); //1个地址 1个功能码 2个CRC 1个错误码 m_nState = MODBUSS_INFO; } else { switch (buffer[1]) { //根据功能码获取需要数据长度 case MODBUSC_F01: case MODBUSC_F02: case MODBUSC_F03: case MODBUSC_F04: m_nNeedCount = (buffer[2] + 4 + 1); //1个地址 1个功能码 2个CRC 1个长度 break; case MODBUSC_F05: case MODBUSC_F06: case MODBUSC_F15: case MODBUSC_F16: m_nNeedCount = (4 + 2 + 2); //1个地址 1个功能码 2个CRC 2个寄存器地址 2个寄存器值 break; case MODBUSC_F07: case MODBUSC_F08: case MODBUSC_F11: case MODBUSC_F12: case MODBUSC_F17: break; case MODBUSC_F20: case MODBUSC_F21: m_nNeedCount = (buffer[2] + 4 + 1); //1个地址 1个功能码 2个CRC 1个长度 break; case MODBUSC_F22: m_nNeedCount = (4 + 2 + 2 + 2); //1个地址 1个功能码 2个CRC 2个参考地址 2个And_Mask 2个Or_Mask break; case MODBUSC_F23: m_nNeedCount = (buffer[2] + 4 + 1); //1个地址 1个功能码 2个CRC 1个长度 break; case MODBUSC_F24: break; case MODBUSC_F43: m_nNeedCount = (4 + 9); break; case MODBUSC_F26: m_nNeedCount = (buffer[2] + 4 + 1); //1个地址 1个功能码 2个CRC 1个长度 break; } if (m_nNeedCount > 255) { vLog(LOG_ERROR, "data received error. m_nNeedCount is: %d too long for the buf.\r\n", m_nNeedCount); bFailed = TRUE; } else { m_nState = MODBUSS_INFO; } } } else if (m_nState == MODBUSS_INFO) { if (((buffer[1] & 0x7f) != MODBUSC_F01) && ((buffer[1] & 0x7f) != MODBUSC_F02) && ((buffer[1] & 0x7f) != MODBUSC_F03) && ((buffer[1] & 0x7f) != MODBUSC_F04) && ((buffer[1] & 0x7f) != MODBUSC_F05) && ((buffer[1] & 0x7f) != MODBUSC_F06) && ((buffer[1] & 0x7f) != MODBUSC_F07) && ((buffer[1] & 0x7f) != MODBUSC_F08) && ((buffer[1] & 0x7f) != MODBUSC_F11) && ((buffer[1] & 0x7f) != MODBUSC_F12) && ((buffer[1] & 0x7f) != MODBUSC_F15) && ((buffer[1] & 0x7f) != MODBUSC_F16) && ((buffer[1] & 0x7f) != MODBUSC_F17) && ((buffer[1] & 0x7f) != MODBUSC_F20) && ((buffer[1] & 0x7f) != MODBUSC_F21) && ((buffer[1] & 0x7f) != MODBUSC_F22) && ((buffer[1] & 0x7f) != MODBUSC_F23) && ((buffer[1] & 0x7f) != MODBUSC_F24) && ((buffer[1] & 0x7f) != MODBUSC_F43) && ((buffer[1] & 0x7f) != MODBUSC_F26)) { bFailed = TRUE; } else { checkSum = buffer[m_nNeedCount - 2]; checkSum <<= 8; checkSum &= 0xff00; checkSum |= buffer[m_nNeedCount - 1]; if (checkSum != GetCRC16(buffer, m_nNeedCount - 2)) { bFailed = TRUE; } else { DropData(m_nNeedCount); if ((buffer[1] & 0x80) == 0x80) { m_nCurFrame = 0; } //process data else { if (OnReceiveData(buffer, buffer[2])) { m_nCurFrame = 0; } } DisplayRxData(buffer, m_nNeedCount, TRUE); m_nState = MODBUSS_SYNC; } } } else { if (((buffer[1] & 0x7f) == MODBUSC_F01) || ((buffer[1] & 0x7f) == MODBUSC_F02) || ((buffer[1] & 0x7f) == MODBUSC_F03) || ((buffer[1] & 0x7f) == MODBUSC_F04) || ((buffer[1] & 0x7f) == MODBUSC_F05) || ((buffer[1] & 0x7f) == MODBUSC_F06) || ((buffer[1] & 0x7f) == MODBUSC_F07) || ((buffer[1] & 0x7f) == MODBUSC_F08) || ((buffer[1] & 0x7f) == MODBUSC_F11) || ((buffer[1] & 0x7f) == MODBUSC_F12) || ((buffer[1] & 0x7f) == MODBUSC_F15) || ((buffer[1] & 0x7f) == MODBUSC_F16) || ((buffer[1] & 0x7f) == MODBUSC_F17) || ((buffer[1] & 0x7f) == MODBUSC_F20) || ((buffer[1] & 0x7f) == MODBUSC_F21) || ((buffer[1] & 0x7f) == MODBUSC_F22) || ((buffer[1] & 0x7f) == MODBUSC_F23) || ((buffer[1] & 0x7f) == MODBUSC_F24) || ((buffer[1] & 0x7f) == MODBUSC_F43) || ((buffer[1] & 0x7f) == MODBUSC_F26)) { m_nNeedCount = 3; m_nState = MODBUSS_CTRL; } else { m_nNeedCount = 2; bFailed = TRUE; } } if (bFailed) { DropData(1); DisplayRxData(buffer, 1, FALSE); m_nNeedCount = 2; m_nState = MODBUSS_SYNC; } } ////////////////////////////////////////////////// // process recv data // ////////////////////////////////////////////////// //process polling command int uid; CHostModbusRtuProcessItem *pItem = (CHostModbusRtuProcessItem *)GetCurItem(); if (NULL == pItem) return TRUE; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) return TRUE; if (GetSpace() == MAX_PORT_BUFFER_SIZE && (m_nCurFrame == 0) && m_nNeedSend) { count = 0; if (GetYKFrame(pItem, buffer, count, m_nCurFrame)) { //insert yk command } else if (GetYTFrame(pItem, buffer, count, m_nCurFrame)) { //insert yt command } else if (pItem->m_nFramePoll & MODBUSP_SET_TIME_FRAME) { pItem->m_nFramePoll &= ~MODBUSP_SET_TIME_FRAME; if (GetSetTimeFrame(pItem, buffer, count)) { m_nCurFrame = 0; } } else if (pItem->m_nFramePoll & MODBUSP_GET_DATA_FRAME) { pItem->m_nFramePoll &= ~MODBUSP_GET_DATA_FRAME; if (GetReadDataFrame(pItem, buffer, count)) { m_nCurFrame = m_nFrameType; } } if (count >= 2) { checkSum = GetCRC16(buffer, count); buffer[count] = (checkSum >> 8) & 0x00ff; buffer[count + 1] = checkSum & 0x00ff; //发送前清除接收缓冲区所有数据 int tmplen = GetDataCount(); if (tmplen > 0) { BYTE *tmpbuf = new BYTE[tmplen+1]; memset(tmpbuf, 0, (tmplen+1)); GetData(tmpbuf, tmplen); DropData(tmplen); DisplayRxData(tmpbuf, tmplen, FALSE); delete tmpbuf; tmpbuf = NULL; } if (WriteData(buffer, count + 2)) { DisplayTxData(buffer, count + 2, TRUE); } m_nSendPoint = system32.ticks;//0; m_nNeedCount = 2; m_nState = MODBUSS_SYNC; m_nNeedSend = FALSE; FeedDog(); } } return TRUE; } BOOLEAN CHostModbusRtuProcess::OnTimer(void) { int uid; CHostModbusRtuProcessItem* pItem; if (!CPortProcess::OnTimer()) return FALSE; m_nCount++; if (m_nCurFrame != 0) { if (m_nSendPoint && (m_nSendPoint + m_nTimeout) <= system32.ticks) { //0.5 second command time out //超时清除接收缓冲区所有数据 int tmplen = GetDataCount(); if (tmplen > 0) { BYTE *tmpbuf = new BYTE[tmplen+1]; memset(tmpbuf, 0, (tmplen+1)); GetData(tmpbuf, tmplen); DropData(tmplen); DisplayRxData(tmpbuf, tmplen, FALSE); delete tmpbuf; tmpbuf = NULL; } m_nNeedCount = 2; m_nState = MODBUSS_SYNC; m_nSendPoint = 0; m_nCurFrame = 0; } } if (m_nCurFrame == 0 && (m_nCount % PollGap()) == 0) { pItem = (CHostModbusRtuProcessItem *)GetNextItem(); if (pItem == NULL) return TRUE; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) return TRUE; m_nNeedSend = TRUE; struModbusExtFrame* frame = pItem->GetNextFrame(); if (frame != NULL) { m_nFrameType = frame->FrameType; m_nCurFuncCode = frame->FuncCode; m_nCurBeginReg = frame->RegBegin; m_nCurRegCount = frame->RegCount; pItem->m_nFramePoll |= MODBUSP_GET_DATA_FRAME; return TRUE; } } return TRUE; } BOOLEAN CHostModbusRtuProcess::GetYKFrame(CHostModbusRtuProcessItem *pItem, BYTE* pBuf, int& count, DWORD& frame) { int uid; BYTE result; BYTE* pData; if (NULL == pItem) return FALSE; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) return FALSE; if (NULL == pBuf) return FALSE; pData = pBuf; if (!GetUnitYK(uid, m_nYKOrder, m_bYKValue, m_nYKState, result)) return FALSE; vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is %s result is %s.\n", uid, m_nYKOrder, (m_bYKValue ? "ClOSE" : "TRIP"), val_to_str(m_nYKState, yk_state, "STATE = %d"), val_to_str(result, yk_result, "RESULT = %d")); BYTE* m_param; BYTE nFun; //功能码 BOOLEAN nNeedSelect; //遥控需要选择 WORD nReg = 0xffff, nVal = 0; WORD nCloseSelReg, nCloseExecReg, nCloseEscReg, nCloseValue; //合闸命令参数 WORD nOpenSelReg, nOpenExecReg, nOpenEscReg, nOpenValue; //分闸命令参数 m_param = GetUnitYKParamByPoint(uid, m_nYKOrder); if (NULL == m_param) { vLog(LOG_ERROR, "get yk param error.\n"); return FALSE; } nFun = m_param[0]; //功能码占一个字节 nNeedSelect = m_param[1]; //遥控是否需要选择 nCloseSelReg = MAKEWORD(m_param[4], m_param[5]); //选择合寄存器 nCloseExecReg = MAKEWORD(m_param[6], m_param[7]); //执行合寄存器 nCloseEscReg = MAKEWORD(m_param[8], m_param[9]); //撤销合寄存器 nCloseValue = MAKEWORD(m_param[10], m_param[11]); //合 nOpenSelReg = MAKEWORD(m_param[12], m_param[13]); //选择分寄存器 nOpenExecReg = MAKEWORD(m_param[14], m_param[15]); //执行分寄存器 nOpenEscReg = MAKEWORD(m_param[16], m_param[17]); //撤销分寄存器 nOpenValue = MAKEWORD(m_param[18], m_param[19]); //分 if (m_nYKState == YKS_SELREQ) { //遥控选择 if (m_bYKValue) { nReg = nCloseSelReg; nVal = nCloseValue; } else { nReg = nOpenSelReg; nVal = nOpenValue; } if (0xffff == nReg || !nNeedSelect) { //寄存器无效,遥控无须选择 SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_SELED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return FALSE; } else { frame = MODBUSP_YK_SELECT; } } else if (m_nYKState == YKS_EXEREQ) { //遥控执行 if (m_bYKValue) { nReg = nCloseExecReg; nVal = nCloseValue; } else { nReg = nOpenExecReg; nVal = nOpenValue; } if (0xffff == nReg) { vLog(LOG_ERROR, "该设备遥控执行寄存器配置错误。\n"); return FALSE; } frame = MODBUSP_YK_EXECUTE; } else if (m_nYKState == YKS_ABRREQ) { //遥控撤销 if (m_bYKValue) { nReg = nCloseEscReg; nVal = nCloseValue; } else { nReg = nOpenEscReg; nVal = nOpenValue; } if (0xffff == nReg || !nNeedSelect) { //寄存器无效 SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_ABRED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return FALSE; } frame = MODBUSP_YK_CANCEL; } else if ((m_nYKState == YKS_SELING || m_nYKState == YKS_SELED) && result == YKR_OVER) { //遥控撤销 if (m_bYKValue) { nReg = nCloseEscReg; nVal = nCloseValue; } else { nReg = nOpenEscReg; nVal = nOpenValue; } if (0xffff == nReg || !nNeedSelect) { //寄存器无效 SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_ABRED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return FALSE; } frame = MODBUSP_YK_CANCEL; } //modify by assouan for clean; pData[0] = pItem->m_physicsAddress; pData[1] = nFun; pData[2] = (nReg >> 8) & 0x00ff; pData[3] = nReg & 0x00ff; if (nFun == MODBUSC_F05 || nFun == MODBUSC_F06) { pData[4] = (nVal >> 8) & 0x00ff; pData[5] = nVal & 0x00ff; count = 6; } else if (nFun == MODBUSC_F15) { pData[4] = 0x00; pData[5] = 0x01; pData[6] = 0x01; pData[7] = (BYTE)LOBYTE(nVal); count = 8; } else if (nFun == MODBUSC_F16) { pData[4] = 0x00; pData[5] = 0x01; pData[6] = 0x02; pData[7] = (nVal >> 8) & 0x00ff; pData[8] = nVal & 0x00ff; count = 9; } else { vLog(LOG_ERROR, "该设备遥控功能码配置错误,不可能为:%d.\n", nFun); return FALSE; } return TRUE; } ////////////////////////////////////////////////////////////////////////// // yt start // ////////////////////////////////////////////////////////////////////////// BOOLEAN CHostModbusRtuProcess::GetYTFrame(CHostModbusRtuProcessItem *pItem, BYTE* pBuf, int& count, DWORD& frame) { int uid; BYTE result; BYTE* pData; if (NULL == pItem) return FALSE; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) return FALSE; if (NULL == pBuf) return FALSE; pData = pBuf; if (!GetUnitYT(uid, m_nYTOrder, m_dwYTValue, m_nYTState, result)) { return FALSE; } vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is %s result is %s.\n", uid, m_nYTOrder, m_dwYTValue, val_to_str(m_nYTState, yt_state, "STATE = %d"), val_to_str(result, yt_result, "RESULT = %d")); BYTE* m_param; BYTE nFun; //功能码 BYTE nSetType; //设置方式 0单寄存器,1双寄存器 BOOLEAN nNeedSelect; //遥设需要选择 WORD nReg = 0xffff; WORD nSelReg, nExecReg, nEscReg; //合闸命令参数 m_param = GetUnitYTParamByPoint(uid, m_nYTOrder); if (NULL == m_param) return FALSE; nSetType = m_param[0]; //0 16位整型值;1 32位整型值;2 32位浮点数值; nFun = m_param[1]; //功能码占一个字节 nNeedSelect = m_param[2]; //遥控是否需要选择 nSelReg = MAKEWORD(m_param[4], m_param[5]); //选择寄存器 nExecReg = MAKEWORD(m_param[6], m_param[7]); //执行寄存器 nEscReg = MAKEWORD(m_param[8], m_param[9]); //撤销寄存器 if (m_nYTState == YTS_SELREQ) { //遥设选择 nReg = nSelReg; if (0xffff == nReg || !nNeedSelect) { //寄存器无效,遥设无须选择 SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_SELED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return FALSE; } else { frame = MODBUSP_YT_SELECT; } } else if (m_nYTState == YTS_EXEREQ) { //遥设执行 nReg = nExecReg; if (0xffff == nReg) return FALSE; frame = MODBUSP_YT_EXECUTE; } else if (m_nYTState == YTS_ABRREQ) { //遥设撤销 nReg = nEscReg; if (0xffff == nReg || !nNeedSelect) { //寄存器无效 SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_ABRED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return FALSE; } frame = MODBUSP_YT_CANCEL; } else if ((m_nYTState == YTS_SELING || m_nYTState == YTS_SELED) && result == YTR_OVER) { //遥设撤销 nReg = nEscReg; if (0xffff == nReg || !nNeedSelect) { //寄存器无效 SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_ABRED, YTR_SUCC); vLog(LOG_WARN, "Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return FALSE; } frame = MODBUSP_YT_CANCEL; } //modify by assouan for clean; pData[0] = pItem->m_physicsAddress; pData[1] = nFun; pData[2] = (nReg >> 8) & 0x00ff; pData[3] = nReg & 0x00ff; if (nFun == MODBUSC_F06) { pData[4] = (m_dwYTValue >> 8) & 0x00ff; pData[5] = m_dwYTValue & 0x00ff; count = 6; } else if (nFun == MODBUSC_F16) { if (nSetType == 0) { pData[4] = 0x00; pData[5] = 0x01; pData[6] = 0x02; pData[7] = (m_dwYTValue >> 8) & 0x00ff; pData[8] = m_dwYTValue & 0x00ff; count = 9; } else if (nSetType == 1) { pData[4] = 0x00; pData[5] = 0x02; pData[6] = 0x04; pData[7] = (m_dwYTValue >> 24) & 0x00ff; pData[8] = (m_dwYTValue >> 16) & 0x00ff; pData[9] = (m_dwYTValue >> 8) & 0x00ff; pData[10] = m_dwYTValue & 0x00ff; count = 11; } else if (nSetType == 2) { pData[4] = 0x00; pData[5] = 0x02; pData[6] = 0x04; pData[7] = (m_dwYTValue >> 8) & 0x00ff; pData[8] = m_dwYTValue & 0x00ff; pData[9] = (m_dwYTValue >> 24) & 0x00ff; pData[10] = (m_dwYTValue >> 16) & 0x00ff; count = 11; } } else return FALSE; return TRUE; } ////////////////////////////////////////////////////////////////////////// // yt end // ////////////////////////////////////////////////////////////////////////// BOOLEAN CHostModbusRtuProcess::GetSetTimeFrame(CHostModbusRtuProcessItem *pItem, BYTE* /*pData*/, int& count) { if (NULL == pItem) return FALSE; count = 0; return FALSE; } BOOLEAN CHostModbusRtuProcess::GetReadDataFrame(CHostModbusRtuProcessItem *pItem, BYTE* pData, int& count) { if (NULL == pItem) return FALSE; if (m_nFrameType == 0) return FALSE; if (m_nCurFuncCode == 0) return FALSE; pData[0] = pItem->m_physicsAddress; pData[1] = (BYTE)m_nCurFuncCode; pData[2] = (m_nCurBeginReg >> 8) & 0x00ff; pData[3] = m_nCurBeginReg & 0x00ff; pData[4] = (m_nCurRegCount >> 8) & 0x00ff; pData[5] = m_nCurRegCount & 0x00ff; count = 6; return TRUE; } BOOLEAN CHostModbusRtuProcess::OnReceiveData(BYTE* pData, int count) { int uid; CHostModbusRtuProcessItem *pItem; uid = GetUnitByAddr(pData, 1); if (uid < 0 || uid >= UNIT_NUM) return FALSE; int order = GetOrderByUnitID(uid); if (order < 0 || order >= PROCESS_UNIT_NUM) return FALSE; pItem = (CHostModbusRtuProcessItem *)GetItem(order); if (NULL == pItem) return FALSE; UnitFeedDog(uid); if (m_nCurFrame == MODBUSP_READ_YX1) { return OnReceiveYXData(pItem, &pData[3], count); } else if (m_nCurFrame == MODBUSP_READ_YC1) { return OnReceiveYCData(pItem, &pData[3], count); } else if (m_nCurFrame == MODBUSP_READ_YM1) { return OnReceiveYMData(pItem, &pData[3], count); } else if (m_nCurFrame == MODBUSP_READ_SOE) { return TRUE; } else if (MODBUSP_YK_EXECUTE == m_nCurFrame) { SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_EXEED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_EXEED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return TRUE; } else if (MODBUSP_YK_SELECT == m_nCurFrame) { SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_SELED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return TRUE; } else if (MODBUSP_YK_CANCEL == m_nCurFrame) { SetUnitYK(uid, m_nYKOrder, m_bYKValue, YKS_ABRED, YKR_SUCC); vLog(LOG_WARN, "Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC.\n", uid, m_nYKOrder, (m_bYKValue ? "CLOSE" : "TRIP")); return TRUE; } else if (MODBUSP_YT_EXECUTE == m_nCurFrame) { SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_EXEED, YTR_SUCC); vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_EXEED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return TRUE; } else if (MODBUSP_YT_SELECT == m_nCurFrame) { SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_SELED, YTR_SUCC); vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return TRUE; } else if (MODBUSP_YT_CANCEL == m_nCurFrame) { SetUnitYT(uid, m_nYTOrder, m_dwYTValue, YTS_ABRED, YTR_SUCC); vLog(LOG_DEBUG, "Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC.\n", uid, m_nYTOrder, m_dwYTValue); return TRUE; } return FALSE; } BOOLEAN CHostModbusRtuProcess::OnReceiveYXData(CHostModbusRtuProcessItem *pItem, BYTE* pData, int count) { int uid; int i, j; int point; BYTE param[4]; WORD reg; BOOLEAN yxVal; if (pItem == NULL) return FALSE; uid = pItem->GetUnitID(); if (uid < 0) return FALSE; reg = m_nCurBeginReg; param[0] = m_nCurFuncCode; if (MODBUSC_F03 == m_nCurFuncCode || MODBUSC_F04 == m_nCurFuncCode) { //03功能码读取Holdings WORD nValue; WORD nTemp = 0x0001; for (i = 0; i < count; i += 2) { nValue = (pData[i] << 8) | pData[i+1]; nTemp = 0x0001; param[1] = LOBYTE(reg); param[2] = HIBYTE(reg); reg++; for (j = 0; j < 16; j++) { param[3] = j; point = GetUnitYXPointByParam(uid, param, 4); if (point >= 0) { yxVal = SPI_OFF; if ((nValue) & nTemp) { yxVal = SPI_ON; } SetUnitYX(uid, point, yxVal); } nTemp <<= 1; } } } else if (MODBUSC_F01 == m_nCurFuncCode || MODBUSC_F02 == m_nCurFuncCode) { //01 02功能码读取Coils和Status BYTE *nValue = pData; BYTE nTemp = 0x01; for (i = 0; i < count; i++) { nTemp = 0x01; for (j = 0; j < 8; j++) { param[1] = LOBYTE(reg); param[2] = HIBYTE(reg); reg++; point = GetUnitYXPointByParam(uid, param, 3); if (point >= 0) { yxVal = SPI_OFF; if ((*nValue) & nTemp) { yxVal = SPI_ON; } SetUnitYX(uid, point, yxVal); } nTemp <<= 1; } nValue++; } } return TRUE; } BOOLEAN CHostModbusRtuProcess::OnReceiveYCData(CHostModbusRtuProcessItem *pItem, BYTE* pData, int count) { int uid; int i; BYTE* pBuf; BYTE* pParam; BYTE param[8]; DWORD nValue = 0; LONG bin_value; float f_val; int point; WORD reg; BYTE reg_count, value_type, sign_mark; if (pItem == NULL) return FALSE; uid = pItem->GetUnitID(); if (uid < 0) return FALSE; pBuf = pData; reg = m_nCurBeginReg; param[0] = m_nCurFuncCode; for (i = 0; i < count;) { param[1] = LOBYTE(reg); param[2] = HIBYTE(reg); point = GetUnitYCPointByParam(uid, param, 3); if (point >= 0) { //获得合法点号 pParam = GetUnitYCParamByPoint(uid, point); if (pParam != NULL) { reg_count = pParam[3]; value_type = pParam[4]; sign_mark = pParam[5]; if ((1 == reg_count) && (2 == value_type)) { //16位归一化值 if (2 == value_type) { if (sign_mark == 0) nValue = (DWORD)(WORD)((pBuf[0] << 8) | pBuf[1]); else nValue = (DWORD)(short)((pBuf[0] << 8) | pBuf[1]); SetUnitYC(uid, point, (LONG)nValue); } else if (8 == value_type) { if (sign_mark == 0) nValue = (DWORD)(WORD)((pBuf[0] << 8) | pBuf[1]); else nValue = (DWORD)(short)((pBuf[0] << 8) | pBuf[1]); nValue = bcd_to_int((const BYTE*)&nValue, sizeof(WORD)); SetUnitYC(uid, point, (LONG)nValue); } pBuf += 2; i += 2; reg++; } else if (2 == reg_count) { //32位测量值 if (0 == value_type) { //浮点数,高位在第一个寄存器 nValue = (DWORD)(pBuf[0] << 24 | pBuf[1] << 16 | pBuf[2] << 8 | pBuf[3]); memcpy(&f_val, &nValue, 4); SetUnitYC(uid, point, f_val); //nValue = (DWORD)(f_val * 1000); } else if (1 == value_type) { nValue = (DWORD)(pBuf[2] << 24 | pBuf[3] << 16 | pBuf[0] << 8 | pBuf[1]); memcpy(&f_val, &nValue, 4); SetUnitYC(uid, point, f_val); //nValue = (DWORD)(f_val * 1000); } else if (3 == value_type) { //归一化值,高位在第一个寄存器 nValue = (DWORD)(pBuf[0] << 24 | pBuf[1] << 16 | pBuf[2] << 8 | pBuf[3]); SetUnitYC(uid, point, (LONG)nValue); } else if (4 == value_type) { //归一化值,高位在第二个寄存器 nValue = (DWORD)(pBuf[2] << 24 | pBuf[3] << 16 | pBuf[0] << 8 | pBuf[1]); SetUnitYC(uid, point, (LONG)nValue); } else if (5 == value_type) { nValue = (DWORD)(pBuf[3] << 24 | pBuf[2] << 16 | pBuf[1] << 8 | pBuf[0]); memcpy(&f_val, &nValue, 4); SetUnitYC(uid, point, f_val); } else if (6 == value_type) { //32位bcd数据高位在第一个寄存器 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); bin_value = (LONG)bcd_to_int((const BYTE*)&nValue, sizeof(DWORD)); SetUnitYC(uid, point, bin_value); } else if (7 == value_type) { //32位bcd数据高位在第二个寄存器 nValue = (DWORD)(pBuf[2] << 24 | pBuf[3] << 16 | pBuf[0] << 8 | pBuf[1]); bin_value = (LONG)bcd_to_int((const BYTE*)&nValue, sizeof(DWORD)); SetUnitYC(uid, point, bin_value); } pBuf += 4; i += 4; reg += 2; } } } else { pBuf += 2; i += 2; reg++; } } return TRUE; } BOOLEAN CHostModbusRtuProcess::OnReceiveYMData(CHostModbusRtuProcessItem *pItem, BYTE* pData, int count) { int i; int point; int uid; BYTE* pBuf; BYTE* pParam; BYTE nParam[4]; BYTE value_type; WORD reg; DWORD nValue = 0; float f_val; DWORD dw[2]; //双精度转换中间变量 double d_val; DWORD bin_value; if (pItem == NULL) return FALSE; uid = pItem->GetUnitID(); if (uid < 0) return FALSE; pBuf = pData; reg = m_nCurBeginReg; nParam[0] = m_nCurFuncCode; for (i = 0; i < count; ) { nParam[1] = LOBYTE(reg); nParam[2] = HIBYTE(reg); point = GetUnitYMPointByParam(uid, nParam, 3); if (point >= 0) { //获得有效点号 pParam = GetUnitYMParamByPoint(uid, point); if (NULL != pParam) { //获得有效参数 value_type = pParam[4]; if (0 == value_type) { //16位无符号整型 nValue = (pBuf[0] << 8) | pBuf[1]; SetUnitYM(uid, point, nValue); pBuf += 2; i += 2; reg++; } else if (1 == value_type) { //32位无符号整型高位在第一个寄存器 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); SetUnitYM(uid, point, nValue); pBuf += 4; reg += 2; i += 4; } else if (2 == value_type) { //32位整型高位在第一个寄存器 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); SetUnitYM(uid, point, nValue); pBuf += 4; reg += 2; i += 4; } else if (3 == value_type) { //32位无符号整型高位在第二个寄存器 nValue = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); SetUnitYM(uid, point, nValue); pBuf += 4; reg += 2; i += 4; } else if (4 == value_type) { //32位整型高位在第二个寄存器 nValue = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); SetUnitYM(uid, point, nValue); pBuf += 4; reg += 2; i += 4; } else if (5 == value_type) { //32位浮点数高位在第一个寄存器 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); memcpy(&f_val, &nValue, 4); SetUnitYM(uid, point, (DWORD)(f_val * 10)); pBuf += 4; reg += 2; i += 4; } else if (6 == value_type) { //32位浮点数高位在第二个寄存器 nValue = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); memcpy(&f_val, &nValue, 4); SetUnitYM(uid, point, (DWORD)(f_val * 10)); pBuf += 4; reg += 2; i += 4; } else if (7 == value_type) { //64位浮点数高位在第一个寄存器 dw[1] = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); dw[0] = (DWORD)((pBuf[6] << 24) | (pBuf[7] << 16) | (pBuf[4] << 8) | pBuf[5]); memcpy(&d_val, dw, 8); SetUnitYM(uid, point, (DWORD)(d_val)); pBuf += 8; reg += 4; i += 8; } else if (8 == value_type) { dw[0] = (DWORD)((pBuf[2] << 24) | (pBuf[3] << 16) | (pBuf[0] << 8) | pBuf[1]); dw[1] = (DWORD)((pBuf[6] << 24) | (pBuf[7] << 16) | (pBuf[4] << 8) | pBuf[5]); memcpy(&d_val, dw, 8); SetUnitYM(uid, point, (DWORD)(d_val)); pBuf += 8; reg += 4; i += 8; } else if (9 == value_type) { nValue = (DWORD)((pBuf[3] << 24) | (pBuf[2] << 16) | (pBuf[1] << 8) | pBuf[0]); memcpy(&f_val, &nValue, 4); SetUnitYM(uid, point, (DWORD)(f_val * 10)); pBuf += 4; reg += 2; i += 4; } else if (10 == value_type) { //32位bcd数据 nValue = (DWORD)((pBuf[0] << 24) | (pBuf[1] << 16) | (pBuf[2] << 8) | pBuf[3]); bin_value = bcd_to_int((const BYTE*)&nValue, sizeof(DWORD)); SetUnitYM(uid, point, bin_value); pBuf += 4; reg += 2; i += 4; } else { //无配置 pBuf += 2; reg++; i += 2; } } } else { pBuf += 2; i += 2; reg++; } } return TRUE; }