/** @ingroup MBUSA * Modbus ASCII 形式の出力を行う。 * * @param psSerStream * @param u8addr アドレス(1バイト目) * @param u8cmd コマンド(2バイト目) * @param pDat ペイロード * @param u16len ペイロードの長さ */ void vSerOutput_ModbusAscii(tsFILE *psSerStream, uint8 u8addr, uint8 u8cmd, uint8 *pDat, uint16 u16len) { int i; uint8 u8lrc = 0; // NULL buffer if (pDat == NULL || u16len == 0) return; // Header byte vPutChar(psSerStream, ':'); // Address and Cmd vPutByte(psSerStream, u8addr, &u8lrc); vPutByte(psSerStream, u8cmd, &u8lrc); // Payload for (i = 0; i < u16len; i++) { vPutByte(psSerStream, *pDat++, &u8lrc); } // 2の補数の計算 (LRC) u8lrc = ~u8lrc + 1; vPutByte(psSerStream, u8lrc, NULL); // Trailer byte vPutChar(psSerStream, 0x0D); vPutChar(psSerStream, 0x0A); }
/** @ingroup MBUSA * 1バイトを16進数2文字で出力する (0xA5 -> "A5") * * @param psSerStream 出力先 * @param u8byte 出力したいバイト列 * @param pu8lrc LRC計算用 */ static inline void vPutByte(tsFILE *psSerStream, uint8 u8byte, uint8 *pu8lrc) { static const uint8 au8tbl[] = "0123456789ABCDEF"; uint8 u8OutH, u8OutL; u8OutH = au8tbl[u8byte >> 4]; u8OutL = au8tbl[u8byte & 0x0F]; vPutChar(psSerStream, u8OutH); vPutChar(psSerStream, u8OutL); if (pu8lrc) { #ifdef LRC_CHARBASE *pu8lrc += u8OutH; *pu8lrc += u8OutL; #else *pu8lrc += u8byte; #endif } }
/** @ingroup SERCMD * バイナリ形式の出力 (vOutputメソッド用) * @param pc * @param ps */ static void SerCmdBinary_Output(tsSerCmd_Context *pc, tsFILE *ps) { int i; uint8 u8xor = 0; // NULL buffer if (pc == NULL || pc->au8data == NULL || pc->u16len == 0) return; vPutChar(ps, SERCMD_SYNC_1); vPutChar(ps, SERCMD_SYNC_2); vPutChar(ps, (uint8)(0x80 | (pc->u16len >> 8))); vPutChar(ps, (pc->u16len & 0xff)); for (i = 0; i < pc->u16len; i++) { u8xor ^= pc->au8data[i]; vPutChar(ps, pc->au8data[i]); } vPutChar(ps, u8xor); // XOR check sum vPutChar(ps, 0x4); // EOT }