FreeModbus离散量输入

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lushoumin/article/details/89110221

离散量输入的访问属性为只读

对离散量输入的操作包括:读离散量输入(0x02)

 

在一个远程设备中,使用该功能码读取离散量输入的1 至2000 连续状态。请求PDU 详细说明了起始地址,即指定的第一个输入地址和输入编号。从零开始寻址输入。因此寻址输入1-16 为0-15。根据数据域的每个比特将响应报文中的离散量输入分成为一个输入。指示状态为1= ON 和0=OFF。第一个数据字节的LSB(最低有效位)包括在询问中寻址的输入。其它输入依次类推,一直到这个字节的高位端为止,并在后续字节中从低位到高位的顺序。

如果返回的输入数量不是八的倍数,将用零填充最后数据字节中的剩余比特(一直到字节的高位端)。字节数量域说明了数据的完整字节数。

读离散量输入状态图

/* 读离散量 */
eMBException eMBFuncReadDiscreteInputs(UCHAR *pucFrame, USHORT *usLen)
{
	USHORT usRegAddress;
	USHORT usDiscreteCnt;
	UCHAR ucNBytes;
	UCHAR *pucFrameCur;
	eMBException eStatus = MB_EX_NONE;
	eMBErrorCode eRegStatus;

	/* 校验PDU长度是否合理 */
	if(*usLen == (MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN))
	{
		/* 离散量地址 */
		usRegAddress = (USHORT)(pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8);
		usRegAddress |= (USHORT)(pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1]);
		/* 第1个离散量寻址为0,所以地址加一 */
		usRegAddress++;

		/* 离散量数量 */
		usDiscreteCnt = (USHORT)(pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF] << 8);
		usDiscreteCnt |= (USHORT)(pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF + 1]);

		/* 检查离散量数量是否合理 */
		if((usDiscreteCnt >= 1) &&
			 (usDiscreteCnt < MB_PDU_FUNC_READ_DISCCNT_MAX))
		{
			/* 构建响应 */
			
			/* PDU指针 */
			pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
			/* PDU长度初始化为0 */
			*usLen = MB_PDU_FUNC_OFF;

			/* 功能码 */
			*pucFrameCur++ = MB_FUNC_READ_DISCRETE_INPUTS;
			*usLen += 1;

			/* 字节数 */
			if((usDiscreteCnt & 0x0007) != 0)
			{
				ucNBytes = (UCHAR)(usDiscreteCnt / 8 + 1);
			}
			else
			{
				ucNBytes = (UCHAR)(usDiscreteCnt / 8);
			}
			*pucFrameCur++ = ucNBytes;
			*usLen += 1;

			/* 读取离散量值 */
			eRegStatus = eMBRegDiscreteCB(pucFrameCur, usRegAddress, usDiscreteCnt);
			/* 产生异常 */
			if(eRegStatus != MB_ENOERR)
			{
				/* 错误转化为异常码 */
				eStatus = prveMBError2Exception(eRegStatus);
			}
			/* 未产生异常 */
			else
			{
				/* 数据长度 */
				*usLen += ucNBytes;;
			}
		}
		/* 离散量数量不合理 */
		else
		{
			/* 非法数据值 */
			eStatus = MB_EX_ILLEGAL_DATA_VALUE;
		}
	}
	/* PDU长度不对 */
	else
	{
		/* 非法数据值 */
		eStatus = MB_EX_ILLEGAL_DATA_VALUE;
	}
	
	return eStatus;
}

 

展开阅读全文

没有更多推荐了,返回首页