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

📄 msghdler.cpp

📁 用VC编写的设备通讯程序,里面有很多规约,自己下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				
			case 2:				// analog input
				SetRtuCmdStep(sendInfo->pRtu, 0);
				
				pF3Rsp = (F3RSP *)p_buf;
				if (crc != *(USHORT *)&p_buf[len - 2]) {
					SetPioRecvStatus(pPio, PIO__BAD_CHECKSUM);
				}
				else {
					gix = AINORMSLOT;
					for (i = 0; i < (len - 6) / 2; i++) {
						shtval = byte_swap(pF3Rsp->reg[i]);
						if (shtval & 0x8000) {	// negative
							shtval -= (short)0x8000;	// for bipolar
						}
						else {
							shtval += 0x8000;
						}
						pix = i % PNTGRPMAX;
						value = shtval;
						UpdRtuRawData(sendInfo->pRtu, gix, pix, value);
						if ((i % PNTGRPMAX) == (PNTGRPMAX - 1)) {
							gix++;
						}
					}
				}
				
				// clear polling flag for next polling
				ClrRtuPollSts(sendInfo->pRtu);
				break;
			}
			break;
		case DIGI_COMD:		// digital output command
			pF5Rsp = (F5RSP *)p_buf;
			if (crc != *(USHORT *)&p_buf[len - 2]) {
				SetPioRecvStatus(pPio, PIO__BAD_CHECKSUM);
			}
			if (sendInfo->rGrpIdx == DOPARMSLOT) {	// to read control word

				// send additional polling command
				sendInfo->FuncCode = RELY_COMD;
				sendInfo->cmdIdx   = RLY_CONSET;
				// add a high priority refresh poll
				AddMorePollCmd(sendInfo, TRUE);
			}
			break;
		case ANAL_COMD:		// register output command
			pF5Rsp = (F5RSP *)p_buf;
			if (crc != *(USHORT *)&p_buf[len - 2]) {
				SetPioRecvStatus(pPio, PIO__BAD_CHECKSUM);
			}
			break;
		case RELY_COMD:		// relay control command
			switch (sendInfo->cmdIdx) {
			case RLY_VALQRY:		// 定值查询
				pF3Rsp = (F3RSP *)p_buf;
				startidx = 0;
				cpuidx = sendInfo->rGrpIdx;	// cpu number
				setnum = sendInfo->rPntIdx;	// set number
				setval = GetSetFuncNum(sendInfo->pRtu, cpuidx);
				for (i = 0; i < setval; i++) {
					shtval = byte_swap(pF3Rsp->reg[i]);
					if (!GetSetUpdData(sendInfo->pRtu, cpuidx, startidx, &valtyp, data)) {
						valtyp = 0;
					}
					switch (valtyp) {
					case 1:
						shtval = (shtval == ENGIVALUE) ? 1 : 0;
						break;
					case 2:
						if (shtval == SP9600VAL) {
							shtval = 3;
						}
						else if (shtval == SP4800VAL) {
							shtval = 2;
						}
						else if (shtval == SP2400VAL) {
							shtval = 1;
						}
						else {
							shtval = 0;
						}
						break;
					}
					if ((setidx = PutRlySetValue(sendInfo->pRtu, cpuidx, setnum,
										startidx, (BYTE *)&shtval)) < 0)
						break;
					startidx = setidx;
				}
				// set successful flag, where the last param is type
				// type = 0 for query, type = 1 for value setup
				SetRlySucFlag(sendInfo->pRtu, setnum, 0);
				if (setnum != 0) {			// query working set, replace display
					PutRlySetToActDev(sendInfo->pRtu, cpuidx, setnum);
				}
				// transfer set value to standby cpu
				RelayValueXfr(sendInfo->pRtu, 1);
				break;

			case RLY_CONSET:		// 控制字召唤
				pF3Rsp = (F3RSP *)p_buf;
				gix    = DIPROTSLOT;
				pSts   = (BYTE *)pF3Rsp->reg;
				shtval = byte_swap(pF3Rsp->num);
				for (i = 0; i < shtval; i++) {
					if (*pSts >= CTLWORDON) {
						value = (*pSts == CTLWORDON) ? 1 : 0;
						UpdRtuRawData(sendInfo->pRtu, gix, i, value, 1);
					}
					else {
						if (GetDioInpInfo(sendInfo->pRtu, gix, i, &inpcnt)) {
							if (inpcnt > 2) {
								switch (*pSts) {
								case 0:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 3);
									break;
								case 1:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 3);
									break;
								case 2:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 3);
									break;
								case 3:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 3);
									break;
								case 4:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 3);
									break;
								case 5:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 3);
									break;
								case 6:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 3);
									break;
								case 7:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 3);
									break;
								}
							}
							else {
								switch (*pSts) {
								case 0:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
									break;
								case 1:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 2);
									break;
								case 2:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 0, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
									break;
								case 3:
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 1);
									UpdRtuRawData(sendInfo->pRtu, gix, i, 1, 2);
									break;
								}
							}
						}
					}
					pSts++;
				}
				UpdRtuPntSts(sendInfo->pRtu, 1);
				break;

			case RLY_VALSET:		// 定值设置
				// inform client value setup finished
				SetRlySucFlag(sendInfo->pRtu, 100, 1);	
				break;
			}
			break;
		}
	}
	else {
		// write data to debug buffer if rtu in debug mode
		SetPioRtuDbgInMsg(pPio, sendInfo->pRtu);

		// clear polling flag for next polling
		ClrRtuPollSts(sendInfo->pRtu);
	}

	ClrPioRtuStream(ioStream);
}

static UINT SendCommand(CPio *pPio, REQUEST_MSGS *pMsg, int *respnum)
{
	int    value, setitm, nextitm, item;
	int    grp, pix, ctlcnt;
	UINT   len = 0;
	USHORT setval, cpuidx;
	BYTE   valtyp, *data, *p_buf = GetPioWrtBuf(pPio);
	float  fvalue;
	F3CMD  *pF3Cmd;
	F5CMD  *pF5Cmd;
	F6CMD  *pF6Cmd;
	F16CMD *pF16Cmd;
	SYSTEMTIME sTime;

	switch (pMsg->FuncCode) {
	// digital/analog control types
	case DIGI_COMD:		// digital output command
		// form frame section
		if (pMsg->rGrpIdx < DORESTSLOT) {		// normal do control
			pF5Cmd = (F5CMD *)p_buf;
			pF5Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
			pF5Cmd->func = FUNC_5;
			pF5Cmd->coil = byte_swap(pMsg->rPntIdx + pMsg->cmdIdx);
			pF5Cmd->num  = byte_swap(1);
			pF5Cmd->value = DOONVALUE;
			pF5Cmd->crc  = mod_crc(p_buf, (MODBUS_F5_SIZ - 2 ) );
			len = MODBUS_F5_SIZ;
			*respnum = MODBUS_F5_REPLY_SIZ;
		}
#if 0
		else if (pMsg->rGrpIdx < DOPARMSLOT) {	// reset control
			pF6Cmd = (F6CMD *)p_buf;
			pF6Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
			pF6Cmd->func = FUNC_6;
			pF6Cmd->reg  = byte_swap(pMsg->rPntIdx);
			pF6Cmd->len  = byte_swap(1);
			pF6Cmd->val[0] = 0;
			pF6Cmd->crc  = mod_crc(p_buf, (MODBUS_F6_SIZ - 2 ) );
			len = MODBUS_F6_SIZ;
			*respnum = MODBUS_F6_REPLY_SIZ;
		}
#endif
		else {									// control word, normal
			pF6Cmd = (F6CMD *)p_buf;
			pF6Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
			pF6Cmd->func = FUNC_6;
			if (GetDioCtlInfo(pMsg->pntIdx, &grp, &pix, &ctlcnt)) {
				setval = CTLWORDORG + pix - 1;
				pF6Cmd->reg  = byte_swap(setval);
				pF6Cmd->len  = byte_swap(1);
				if (ctlcnt <= 2) {		// 压板控制字
					pF6Cmd->val[0] = (pMsg->cmdIdx % 2) ? CTLWORDON : CTLWORDOFF;
				}
				else {					// 特殊控制字
					pF6Cmd->val[0] = pMsg->cmdIdx - 1;
				}
				pF6Cmd->crc  = mod_crc(p_buf, (MODBUS_F6_SIZ - 2 ) );
				len = MODBUS_F6_SIZ;
				*respnum = MODBUS_F6_REPLY_SIZ;
			}
		}
		break;

	case ANAL_COMD:		// register output command
		// to be develop
		*respnum = 0;
		break;

	case RELY_COMD:		// relay control command
		switch (pMsg->cmdIdx) {
		case RLY_VALQRY:			// 定值和参数查询
			pF3Cmd = (F3CMD *)p_buf;
			pF3Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
			pF3Cmd->func = FUNC_3;
			cpuidx = pMsg->rGrpIdx;	// cpu number
			if (cpuidx <= 1) {		// 定值查询
				pF3Cmd->reg  = byte_swap(SETWORDORG);
			}
			else {					// 参数查询
				pF3Cmd->reg  = byte_swap(PRMWORDORG);
			}
			setval = GetSetFuncNum(pMsg->pRtu, (BYTE)cpuidx) * 2;
			pF3Cmd->num  = byte_swap(setval);
			pF3Cmd->crc  = mod_crc(p_buf, (MODBUS_F3_SIZ - 2 ) );
			len = MODBUS_F3_SIZ;
			*respnum = MODBUS_F3_SIZ + setval - 2;
			break;
		case RLY_VALSET:			// 定值和参数设置
			pF6Cmd = (F6CMD *)p_buf;
			pF6Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
			pF6Cmd->func = FUNC_6;
			cpuidx = pMsg->rGrpIdx;	// cpu number
			if (cpuidx <= 1) {		// 定值设置
				pF6Cmd->reg  = byte_swap(SETWORDORG);
			}
			else {					// 参数设置
				pF6Cmd->reg  = byte_swap(PRMWORDORG);
			}
			// read modification data from relay device database
			setitm = nextitm = 0;
			data   = (BYTE *)pF6Cmd->val;
			while (item = GetSetUpdData(pMsg->pRtu, (BYTE)cpuidx, nextitm, &valtyp, (BYTE *)&value)) {
				// revert set value to 2 bytes data
				switch (valtyp) {
				case 1:
					setval = value;
					if (setval == 1) {
						setval = ENGIVALUE;
					}
					else {
						setval = CHINVALUE;
					}
					setval = byte_swap(setval);
					break;
				case 2:
					setval = value;
					if (setval == 1) {
						setval = SP2400VAL;
					}
					else if (setval == 2) {
						setval = SP4800VAL;
					}
					else if (setval == 3) {
						setval = SP9600VAL;
					}
					else  {
						setval = SP2400VAL;
					}
					setval = byte_swap(setval);
					break;
				default:
					fvalue = *(float *)&value;
					setval = byte_swap((USHORT)fvalue);
					break;
				}
				*(USHORT *)data = setval;

				nextitm = item;		// go to get next set value
				setitm++;
				data += 2;
			}
			setval = setitm * 2;
			pF6Cmd->len  = byte_swap(setval);
			len = setval + 8;
			*(USHORT *)data  = mod_crc(p_buf, len - 2 );
			*respnum = MODBUS_F6_REPLY_SIZ;
			break;
		case RLY_DEVRST:			// 装置复位
			pF6Cmd = (F6CMD *)p_buf;
			pF6Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
			pF6Cmd->func = FUNC_6;
			pF6Cmd->reg  = 0;
			pF6Cmd->len  = byte_swap(1);
			pF6Cmd->val[0] = 0;
			pF6Cmd->crc  = mod_crc(p_buf, (MODBUS_F6_SIZ - 2 ) );
			len = MODBUS_F6_SIZ;
			*respnum = MODBUS_F6_REPLY_SIZ;
			break;
		case RLY_CONSET:			// 控制字召唤
			pF3Cmd = (F3CMD *)p_buf;
			pF3Cmd->addr = (BYTE)GetRtuNetId(pMsg->pRtu);
			pF3Cmd->func = FUNC_3;
			setval = CTLWORDORG;
			pF3Cmd->reg  = byte_swap(setval);
			setval = GetActGrpPnt(pMsg->pRtu, DIPROTSLOT);
			pF3Cmd->num  = byte_swap(setval);
			pF3Cmd->crc  = mod_crc(p_buf, (MODBUS_F3_SIZ - 2 ) );
			len = MODBUS_F3_SIZ;
			*respnum = MODBUS_F3_SIZ + setval - 2;
			break;
		}
		break;

	case TIME_SYNC:		// time sync command
		
		// form time message section
		GetLocalTime(&sTime);
		pF16Cmd = (F16CMD *)p_buf;
		pF16Cmd->addr = *respnum;
		pF16Cmd->func = FUNC_16;
		pF16Cmd->reg  = 0;
		pF16Cmd->len  = byte_swap(6);
		pF16Cmd->tim[0] = (BYTE)SET_BCD(sTime.wSecond);
		pF16Cmd->tim[1] = (BYTE)SET_BCD(sTime.wMinute);
		pF16Cmd->tim[2] = (BYTE)SET_BCD(sTime.wHour);
		pF16Cmd->tim[3] = (BYTE)SET_BCD(sTime.wDay);
		pF16Cmd->tim[4] = (BYTE)SET_BCD(sTime.wMonth);
		pF16Cmd->tim[5] = (BYTE)SET_BCD(sTime.wYear % 100);
		pF16Cmd->crc  = mod_crc(p_buf, (MODBUS_F16_SIZ - 2 ) );
		len = MODBUS_F16_SIZ;
		*respnum = 0;
		break;
	}

	return len;
}

⌨️ 快捷键说明

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