/** @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
	}
}
Example #3
0
/** @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
}