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

📄 nbbclass.cpp

📁 一个完整的RTU程序源码,用DOS平台,支持16串口,在天津港用的很多,8个规约103,modbus,cdt,1801,u4f
💻 CPP
字号:
#include "sc_cfg.h"
#include "common.h"
#include "class.h"
#include "extern.h"

const INT8U CNbb::nbb_sync_code[6] = {0xeb, 0x90, 0xeb, 0x90, 0xeb, 0x90};
const INT8U CNbb::FRAME_A = 0x61;
const INT8U CNbb::FRAME_B = 0xc2;
const INT8U CNbb::FRAME_C = 0xb3;
const INT8U CNbb::FRAME_D1 = 0xf4;
const INT8U CNbb::FRAME_D2 = 0x85;
const INT8U CNbb::FRAME_E = 0x26;

CNbb::CNbb(INT8U portno):CProtocol(portno)
{
	packet_count = 0;
	frame_count = 0;
	isFrameHead = TRUE;
	source_add = 0;
	dest_add = 0;
	soe_sending = FALSE;
	soe_count = 0;
	yk_preset_err.noerr = TRUE;
	FrameInsertNum = 3;
	sync_flag = FALSE;
	ControlFlag = FALSE;
  RecvIndex = 0;

	len_a = GetProtocolSet(myportno, 0);
	if (len_a < FrameInsertNum) len_a = FrameInsertNum;
	len_b = GetProtocolSet(myportno, 1);
	if (len_a + len_b > 128) len_b = 128 - len_a;
	len_c = GetProtocolSet(myportno, 2);
	if (len_a + len_b + len_c > 128) len_c = 128 - len_a - len_b;
	len_d1 = GetProtocolSet(myportno, 3);
	if (len_d1 > 16) len_d1 = 16;
	len_d2 = GetProtocolSet(myportno, 4);
	if (len_d2 > 32) len_d2 = 32;
	len_e = GetProtocolSet(myportno, 5) / 6 * 6;
	if (len_e <= 0) len_e = 6;

	YxHead = 0xf0;
	YcHead = 0x00;
	YmHead = 0xa0;
}

void CNbb::master_send()
{
	INT8U buf[20];
	BOOLEAN bFrameOver;

	if (!port_free(myportno)) return;

	if (isFrameHead) {
		frame_type = get_frame_type(frame_count);
		frame_length = get_frame_length(frame_type);

		if (frame_length == 0) {
			if (++frame_count > 71) frame_count = 0;
			return;
		}

		memcpy(buf, nbb_sync_code, 6);
		buf[6] = 0x71;
		buf[7] = frame_type;
		buf[8] = frame_length;
		buf[9] = source_add;
		buf[10] = dest_add;
		buf[11] = get_crc8_code(&buf[6], 5);
		isFrameHead = FALSE;
		draw_send_message(myportno, buf, 6, SYNC_COLOR);
		draw_send_message(myportno, buf + 6, 6, SYNC_COLOR);
		com_transfer(myportno, 12, buf);
	}
	else {
		bFrameOver = PacketSend(frame_type, frame_length);

		if (bFrameOver) {
			frame_count++;
			packet_count = 0;
			if (frame_count > 71) frame_count = 0;
			isFrameHead = TRUE;
		}
	}
}

// 0         9          20        30
/* D1AEBAEBAECAEBAEBAECAEBAEBAECAEBAEBAE
	 D2AEBAEBAECAEBAEBAECAEBAEBAECAEBAEBAE */
// 36   40        50        60        70
// frame order

INT8U CNbb::get_frame_type(INT8U count)
{
	INT8U type;
	switch (count) {
		case  1:  case  4:  case  7:  case 10:  case 13:
		case 16:	case 19:  case 22:  case 25:  case 28:
		case 31:  case 34:  case 37:  case 40: 	case 43:
		case 46:  case 49:  case 52:  case 55:  case 58:
		case 61:  case 64:  case 67:  case 70:
			type = FRAME_A;
			break;

		case  3:  case  6:  case 12:  case 15:  case 21:
		case 24:  case 30:  case 33:  case 39:  case 42:
		case 48:  case 51:  case 57:  case 60:  case 66:
		case 69:
			type = FRAME_B;
			break;

		case  9:  case 18:  case 27:  case 45:  case 54:
		case 63:
			type = FRAME_C;
			break;

		case  0:
			type = FRAME_D1;
			break;

		case  36:
			type = FRAME_D2;
			break;

		case  2:  case  5:  case  8:  case 11:  case 14:
		case 17:  case 20:  case 23:  case 26:  case 29:
		case 32:  case 35:  case 38:  case 41:  case 44:
		case 47:  case 50:  case 53:  case 56:  case 59:
		case 62:  case 65:  case 68:  case 71:
			if (is_soe(myportno))	type = FRAME_E;
			else type = FRAME_A;
			break;
	}

	return (type);
}

BOOLEAN CNbb::BWPacketSend(INT8U FrameType, INT8U length)
{
	INT8U buf[20];
	yxbw_record_t temp_yx_bw;

	get_yx_bw(myportno, &temp_yx_bw);
	buf[0] = YxHead + temp_yx_bw.func_code;
	buf[1] = temp_yx_bw.yx_code[0] & 0xff;
	buf[2] = (temp_yx_bw.yx_code[0] >> 8) & 0xff;
	buf[3] = temp_yx_bw.yx_code[1] & 0xff;
	buf[4] = (temp_yx_bw.yx_code[1] >> 8) & 0xff;
	buf[5] = get_crc8_code(&buf[0], 5);
	memcpy(&buf[6], &buf[0], 6);
	memcpy(&buf[12], &buf[0], 6);

	draw_send_message(myportno, &buf[0], 6, YX_COLOR);
	draw_send_message(myportno, &buf[6], 6, YX_COLOR);
	draw_send_message(myportno, &buf[12], 6, YX_COLOR);
	com_transfer(myportno, 18, &buf[0]);

	if (FrameType != FRAME_E) packet_count += FrameInsertNum;
	return (isFrameOver(packet_count, length));
}

BOOLEAN CNbb::YkRetPacketSend(INT8U FrameType, INT8U length, BOOLEAN preset_noerr)
{
	INT8U buf[20];

	buf[0] = 0xe1;
	if (preset_noerr) {
		buf[1] = buf[3] = get_ykret_code(myportno);
		buf[2] = buf[4] = ykreg.ykobj;
	}
	else {
		buf[1] = buf[3] = yk_preset_err.ykcmd;
		buf[2] = buf[4] = yk_preset_err.ykobj;
	}
	buf[5] = get_crc8_code(buf, 5);
	memcpy(&buf[6], &buf[0], 6);
	memcpy(&buf[12], &buf[0], 6);

	draw_send_message(myportno, &buf[0], 6, YK_COLOR);
	draw_send_message(myportno, &buf[6], 6, YK_COLOR);
	draw_send_message(myportno, &buf[12], 6, YK_COLOR);
	com_transfer(myportno, 18, &buf[0]);

	if (FrameType != FRAME_E) packet_count += FrameInsertNum;
	return (isFrameOver(packet_count, length));
}

BOOLEAN CNbb::PacketSend(INT8U type, INT8U length)
{
	BOOLEAN bFrameOver = FALSE;
	if (length - packet_count >= FrameInsertNum) {
		if (is_yx_bw(myportno)) {
			return (BWPacketSend(type, length));
		}
// when you doing yk, you find yk is doing
// so you must return failure check
		if (!yk_preset_err.noerr) {
			bFrameOver = YkRetPacketSend(type, length, yk_preset_err.noerr);
			reset_yk(myportno);
			yk_preset_err.noerr = TRUE;
			return bFrameOver;
		}

		if (is_yk_return(myportno)) {
			bFrameOver = YkRetPacketSend(type, length, yk_preset_err.noerr);
			if (ykreg.ykcheckresult == YKRERROR) reset_yk(myportno);
			ykreg.retflag = FALSE;
			return bFrameOver;
		}
	}

	switch (type) {
		case FRAME_A:
		case FRAME_B:
		case FRAME_C:
			bFrameOver = FrameYCPacketSend(type, length);
			break;

		case FRAME_D1:
			bFrameOver = FrameD1PacketSend(length);
			break;

		case FRAME_D2:
			bFrameOver = FrameD2PacketSend(length);
			break;

		case FRAME_E:
			bFrameOver = FrameEPacketSend(length);
			break;
	}

	return (bFrameOver);
}

BOOLEAN CNbb::FrameYCAssemble(INT8U *buf, INT8U length, INT8U FrameType)
{
	INT16U value = 0;
	INT16U dot = packet_count * 2;

	switch (FrameType) {
		case FRAME_A:
			buf[0] = YcHead + packet_count;
			break;
		case FRAME_B:
			buf[0] = YcHead + len_a + packet_count;
			break;
		case FRAME_C:
			buf[0] = YcHead + len_a + len_b + packet_count;
			break;
	}

	value = get_yc_dot(dot);
	buf[1] = value & 0xff;
	buf[2] = (value >> 8) & 0xff;
	value = get_yc_dot(dot + 1);
	buf[3] = value & 0xff;
	buf[4] = (value >> 8) & 0xff;
	buf[5] = get_crc8_code(&buf[0], 5);

	return (isFrameOver(++packet_count, length));
}

BOOLEAN CNbb::FrameYCPacketSend(INT8U FrameType,INT8U length)
{
	BOOLEAN bFrameOver = FALSE;
	INT8U buf[12];
	INT8U len = 6;

	bFrameOver = FrameYCAssemble(&buf[0], length, FrameType);
	draw_send_message(myportno, &buf[0], 6, YC_COLOR);

	if (!bFrameOver) {
		bFrameOver = FrameYCAssemble(&buf[6], length, FrameType);
		len = 12;
		draw_send_message(myportno, &buf[6], 6, YC_COLOR);
	}
	com_transfer(myportno, len, &buf[0]);

	return bFrameOver;
}

BOOLEAN CNbb::FrameD1Assemble(INT8U *buf, INT8U length)
{
	INT16U yx16 = 0;
	INT16U dot = 0;

	buf[0] = YxHead + packet_count;
	dot = packet_count * 2;
	yx16 = get_yx_16dot(dot);
	buf[1] = yx16 & 0xff;
	buf[2] = yx16 >> 8;

	yx16 = get_yx_16dot(dot + 1);
	buf[3] = yx16 & 0xff;
	buf[4] = yx16 >> 8;
	buf[5] = get_crc8_code(&buf[0], 5);

	return (isFrameOver(++packet_count, length));
}

BOOLEAN CNbb::FrameD1PacketSend(INT8U length)
{
	BOOLEAN bFrameOver = FALSE;
	INT8U buf[12];
	INT8U len = 6;

	bFrameOver = FrameD1Assemble(&buf[0], length);
	draw_send_message(myportno, &buf[0], 6, YX_COLOR);

	if (!bFrameOver) {
		bFrameOver = FrameD1Assemble(&buf[6], length);
		len = 12;
	}
	draw_send_message(myportno, &buf[6], 6, YX_COLOR);
	com_transfer(myportno, len, &buf[0]);

	return bFrameOver;
}

BOOLEAN CNbb::FrameD2Assemble(INT8U *buf, INT8U length)
{
	INT32U value;

	buf[0] = YmHead + packet_count;

	value = get_ym_dot(packet_count);

	buf[1] = value & 0xff;
	buf[2] = (value >> 8) & 0xff;
	buf[3] = (value >> 16) & 0xff;
	buf[4] = (value >> 24) & 0xff;
	buf[5] = get_crc8_code(&buf[0], 5);

	return (isFrameOver(++packet_count, length));
}

BOOLEAN CNbb::FrameD2PacketSend(INT8U length)
{
	BOOLEAN bFrameOver = FALSE;
	INT8U buf[12];
	INT8U len = 6;

	bFrameOver = FrameD2Assemble(&buf[0], length);
	draw_send_message(myportno, &buf[0], 6, YX_COLOR);

	if (!bFrameOver) {
		bFrameOver = FrameD2Assemble(&buf[6], length);
		len = 12;
	}
	draw_send_message(myportno, &buf[6], 6, YX_COLOR);
	com_transfer(myportno, len, &buf[0]);

	return bFrameOver;
}

BOOLEAN CNbb::FrameEAssemble(INT8U *buf, INT8U length)
{
	if (!soe_sending)
		if (is_soe(myportno)) {
			soe_sending = TRUE;
			soe_count = 0;
			get_soe(myportno, &current_soe);
		}

	if (soe_sending) {
		if (++soe_count >= 3) soe_sending = FALSE;
		buf[0] = 0x80;
		buf[1] = current_soe.msecond & 0xff; //msecondl
		buf[2] = current_soe.msecond >> 8; //msecondh
		buf[3] = current_soe.second; //second
		buf[4] = current_soe.minute; //minute
		buf[5] = get_crc8_code(&buf[0], 5);
		buf[6] = 0x81;
		buf[7] = current_soe.hour; //hour
		buf[8] = current_soe.day; //day
		buf[9] = current_soe.status_switch_no & 0xff;
		buf[10] = (current_soe.status_switch_no >> 8) & 0xff;
		buf[11] = get_crc8_code(&buf[6], 5);

		packet_count += 2;
		return (isFrameOver(packet_count, length));
	}

	return (TRUE);
}

BOOLEAN CNbb::FrameEPacketSend(INT8U length)
{
	BOOLEAN bFrameOver = FALSE;
	INT8U buf[12];

	bFrameOver = FrameEAssemble(&buf[0], length);
	draw_send_message(myportno, &buf[0], 6, YX_COLOR);
	draw_send_message(myportno, &buf[6], 6, YX_COLOR);
	com_transfer(myportno, 12, &buf[0]);

	return bFrameOver;
}

void CNbb::master_receive()
{
	while	(get_com_rece_num(myportno) >= 6) {
		if (sync_flag == TRUE) {
			if (ControlFlag == TRUE) {
				read_com_rece_nbytes(&recbuf[RecvIndex], 6, myportno);

				if (memcmp(&recbuf[RecvIndex], nbb_sync_code, 6) == 0) { // begin sync
					ControlFlag = FALSE;
					draw_rece_message(myportno, recbuf, 6, SYNC_COLOR);
					continue;
				}

				if (packet_crc_check(&recbuf[RecvIndex]) == FALSE) {
					ControlFlag = FALSE;
					sync_flag = FALSE;
					continue;
				} // crc check failure need sync again
				draw_rece_message(myportno, &recbuf[RecvIndex], 6, WHITE);

				if ((recbuf[1] == 0x61) || (recbuf[1] == 0xc2)
					|| (recbuf[1] == 0xb3) || (recbuf[1] == 0x7a)) {
					if (RecvIndex >= (recbuf[2] * 6)) { // receive enough word
						identify_packet(recbuf);
						ControlFlag = FALSE;
						sync_flag = FALSE;
					}
					else {
						RecvIndex += 6; // adjust buf index
						if (RecvIndex >= NBB_RECE_BUFSIZE) ControlFlag = FALSE;
					}
				}
				else RecvIndex = 6; // receive other packet such as yc,yx,ym packet
			}
			else {
				read_com_rece_nbytes(recbuf, 6, myportno);
				if (memcmp(&recbuf[0], nbb_sync_code, 6) == 0) { // begin sync
					ControlFlag = FALSE;
					draw_rece_message(myportno, recbuf, 6, SYNC_COLOR);
					continue;
				}

				if (recbuf[0] == 0x71 && packet_crc_check(&recbuf[0])) {
					ControlFlag = TRUE;
					draw_rece_message(myportno, recbuf, 6, SYNC_COLOR);
					RecvIndex = 6;
				}
				else sync_flag = FALSE;
			}
		}
		else {
			get_com_rece_nbytes(recbuf, 6, myportno);
			if (memcmp(recbuf, nbb_sync_code, 6) == 0) { // begin sync
				sync_flag = TRUE;
				ControlFlag = FALSE;
				read_com_rece_nbytes(recbuf, 6, myportno);
				draw_rece_message(myportno, recbuf, 6, SYNC_COLOR);
			}
			else del_com_rece_one(myportno);
		}
	}
}

void CNbb::identify_packet(INT8U *buf)
{
	switch (buf[1]) {
		case 0x61:
			if (buf[2] == 0x03 && buf[6] == 0xe0)
				yk_preset(buf);
				break;

		case 0xc2:	case 0xb3:
			if (buf[2] == 0x03 && (buf[6] == 0xe2 || buf[6] == 0xe3))
				yk_execute(buf);
				break;

		case 0x7a:
			if (buf[2] == 0x02 && buf[6] == 0xee && buf[12] == 0xef)
				time_setting(buf);
				break;
	}
}

void CNbb::yk_preset(INT8U *buf)
{
	if (buf[7] == 0xcc || buf[7] == 0x33) {
		if (buf[8] == 0xff) {
		} //bcd
		else {
			if (!memcmp(&buf[6], &buf[12], 6) && !memcmp(&buf[12], &buf[18], 6)) {
				yk_preset_err.noerr = make_yk_preset(buf[7], buf[8], myportno);
				if (!yk_preset_err.noerr) {
					yk_preset_err.ykobj = buf[8];
					yk_preset_err.ykcmd = buf[7];
				}
			}
		}
	}
}

void CNbb::yk_execute(INT8U *buf)
{
	if (buf[7] == 0xaa || buf[7] == 0x55) {
		if (buf[8] == 0xff) {
		} //bcd
		else {
			if (!memcmp(&buf[6], &buf[12], 6) && !memcmp(&buf[12], &buf[18], 6))
				make_yk_exe(buf[7], buf[8], myportno);
		}
	}
}

void CNbb::time_setting(INT8U *buf)
{
	sclock clk;

	clk.year = buf[16];
	if (clk.year > 80) clk.year += 1900;
	else clk.year += 2000;
	clk.month = buf[15];
	clk.day = buf[14];
	clk.hour = buf[13];
	clk.minute = buf[10];
	clk.second = buf[9];
	clk.msecond = ((buf[8] & 0x03) << 8) + buf[7];
	if (myportno == _CheckTimePort) SetClock(&clk);
}

INT8U CNbb::get_frame_length(INT8U type)
{
	INT8U length;

	switch (type) {
		case FRAME_A:
			length = len_a;	break;
		case FRAME_B:
			length = len_b;	break;
		case FRAME_C:
			length = len_c; break;
		case FRAME_D1:
			length = len_d1; break;
		case FRAME_D2:
			length = len_d2; break;
		case FRAME_E:
			if ((length = get_soe_num(myportno) * 6) > len_e) length = len_e;
			break;
	}

	return (length);
}

BOOLEAN CNbb::isFrameOver(INT8U count, INT8U length)
{
	return (count >= length ? TRUE:FALSE);
}

BOOLEAN CNbb::packet_crc_check(INT8U *buf)
{
	return (get_crc8_code(buf,5) == buf[5] ? TRUE:FALSE);
}

void CNbb::deal()
{
	master_receive();
	master_send();
}

⌨️ 快捷键说明

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