离散量输入的访问属性为只读
对离散量输入的操作包括:读离散量输入(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;
}