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

📄 lfp.cpp

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

void CLfp::initial(INT8U portno)
{
	int i,temp;

	myportno = portno;  //set current port no

	start_add = port_set[myportno].start_addr;
	end_add = port_set[myportno].end_addr;

	for (i = start_add; i <= end_add; i++) {
		LINK_flag[i] = 0;
		send_state[i] = 0;
		fail_count[i] = 0;
	}
	station_add = start_add;
	send_ack_flag = FALSE;
	send_nak_flag = FALSE;
}

void CLfp::send_ack()
{
	INT8U buf[20];

	buf[0] = station_add;
	buf[1] = LFP_ACK;
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 4;

	LFP_send(buf, 5);
}

void CLfp::send_nak()
{
	INT8U buf[20];

	buf[0] = station_add;
	buf[1] = LFP_NAK;
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 4;

	LFP_send(buf, 5);
}

void CLfp::send_C20()
{
	INT8U buf[20];

	buf[0] = station_add;
	buf[1] = LFP_C20;
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 4;

	LFP_send(buf, 5);
}

void CLfp::send_C8() //sync clock
{
	INT8U buf[20];
	sclock sclk;
	GetClock(&sclk);

	buf[0] = 0xff; //boardcasting
	buf[1] = LFP_C8; // time sync
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 12;
	buf[5] = sclk.year % 100;
	buf[6] = sclk.month;
	buf[7] = sclk.day;
	buf[8] = sclk.hour;
	buf[9] = sclk.minute;
	buf[10] = sclk.second;
	buf[11] = sclk.msecond & 0xff;
	buf[12] = (sclk.msecond >> 8) & 0xff;

	LFP_send(buf, 13);
}

void CLfp::send_C15()
{
	INT8U buf[20];

	buf[0] = station_add;
	buf[1] = LFP_C15;
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 4;

	LFP_send(buf, 5);
}

void CLfp::send_C19()
{
	INT8U buf[20];

	buf[0] = station_add;
	buf[1] = LFP_C19;
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 4;

	LFP_send(buf, 5);
}

void CLfp::send_yk_preset()
{
	INT8U buf[20];

	buf[0] = port_yk_info.dev_no;
	buf[1] = LFP_C17;
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 10;
	buf[5] = port_yk_info.yk_no;
	buf[6] = port_yk_info.yk_cmd;
	buf[7] = ~port_yk_info.yk_no;
	buf[8] = ~port_yk_info.yk_cmd;
	buf[9] = port_yk_info.yk_no;
	buf[10] = port_yk_info.yk_cmd;
	LFP_send(buf, 11);
}

void CLfp::send_yk_exec()
{
	INT8U buf[20];

	buf[0] = port_yk_info.dev_no;
	buf[1] = LFP_C18;
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 10;
	buf[5] = port_yk_info.yk_no;
	buf[6] = port_yk_info.yk_cmd;
	buf[7] = ~port_yk_info.yk_no;
	buf[8] = ~port_yk_info.yk_cmd;
	buf[9] = port_yk_info.yk_no;
	buf[10] = port_yk_info.yk_cmd;
	LFP_send(buf, 11);
}

void CLfp::send_yk_esc()
{
	INT8U buf[20];

	buf[0] = port_yk_info.dev_no;
	buf[1] = LFP_C22;
	buf[2] = 1;
	buf[3] = 0;
	buf[4] = 10;
	buf[5] = port_yk_info.yk_no;
	buf[6] = port_yk_info.yk_cmd;
	buf[7] = ~port_yk_info.yk_no;
	buf[8] = ~port_yk_info.yk_cmd;
	buf[9] = port_yk_info.yk_no;
	buf[10] = port_yk_info.yk_cmd;

	LFP_send(buf, 11);
}

void CLfp::LFP_send(INT8U *buf, int len)
{
	INT16U result;

	askbuf[0] = 0xeb;
	askbuf[1] = 0x90;
	askbuf[2] = 0xeb;
	askbuf[3] = 0x90;
	askbuf[4] = 0x02;
	memcpy(&askbuf[5], buf, len);

	result = checksum(&askbuf[5], len);
	askbuf[5 + len] = result & 0xff;
	askbuf[6 + len] = (result >> 8) & 0xff;
	askbuf[7 + len] = 0x03;

	com_transfer(myportno, 8 + len, askbuf);
	draw_send_message(myportno, askbuf, 8 + len, POLL_SEND_COLOR);
}

void CLfp::process_ack(INT8U *buf)
{
}

void CLfp::process_nak(INT8U *buf)
{
}

void CLfp::process_R10(INT8U *buf)
{
	int i, j;
	INT16U yx_no;
	yxbw_record_t temp_yx_bw;
	int no = (buf[9] - 4) / 2;

	for (i = 0; i < no; i++) {
		for (j = 0; j < _TotalYx; j++) {
			if ((myportno == (yx_define[j].portno - 1)) && (yx_define[j].info == buf[i * 2 + 10])
				&& (buf[5] == yx_define[j].devno)) {
				yx_update_db(j, buf[i * 2 + 11]);
				yx_no =  j & 0xfff;
				temp_yx_bw.func_code = yx_no / 32;
				temp_yx_bw.yx_code[0] = dbdata.Yx[yx_no / 32 * 2];
				temp_yx_bw.yx_code[1] = dbdata.Yx[yx_no / 32 * 2 + 1];
				insert_yx_bw(&temp_yx_bw);							// add to yx bw buffer
			}
		}
	}
}

void CLfp::process_R15(INT8U *buf)
{
	INT16U value;
	int i, j;

	int no = (buf[9] - 4) / 2;

	for (i = 0; i < no; i++) {
		for (j = 0; j < _TotalYc; j++) {
			if ((myportno == (yc_define[j].portno - 1)) && (buf[5] == yc_define[j].devno)
				&& (yc_define[j].info == i)) {
				value = buf[i * 2 + 10] + (buf[i * 2 + 11]<<8);
				yc_update_db(j, value);
			}
		}
	}
}

void CLfp::process_R17(INT8U *buf)
{
 INT8U temp1,temp2;
temp1 = ~port_yk_info.yk_no;
temp2 = ~port_yk_info.yk_cmd;
	if (myportno == port_yk_info.yk_des && buf[5] == port_yk_info.dev_no) {
		if ((recbuf[10] == port_yk_info.yk_no) && (recbuf[11] == port_yk_info.yk_cmd) &&
			(recbuf[12] == temp1) &&(recbuf[13] == temp2)	&&
			(recbuf[14] == port_yk_info.yk_no) && (recbuf[15] == port_yk_info.yk_cmd) &&
			(recbuf[9] == 10)) {
			port_yk_info.Y_CHECK = TRUE;
			port_yk_info.check_result = YKROK;
		}
		else {
			port_yk_info.Y_CHECK = TRUE;
			port_yk_info.check_result = FALSE;
		}
	}
}

void CLfp::process_R18(INT8U *buf)
{

}

void CLfp::process_R19(INT8U *buf)
{
	int i, j;
	INT8U value;
	int no = (buf[9] - 4) * 8;

	for (i = 0; i < no; i++) {
		for (j = 0; j < _TotalYx; j++) {
			if ((myportno == (yx_define[j].portno - 1)) && (buf[5] == yx_define[j].devno)
				&& (yx_define[j].info == i)) {
				value = buf[i / 8 + 10] >> (i % 8);
				yx_update_db(j, value);
			}
		}
	}
}

void CLfp::process_R20(INT8U *buf)
{
	int i, j;
	soe_record_t temp_soe;
	sclock sclk;
	INT16U temp;
	int no = (buf[9] - 4) / 7;

	for (i = 0; i < no; i++) {
		for (j = 0; j < _TotalYx; j++) {
			if ((myportno == (yx_define[j].portno - 1)) && (buf[5] == yx_define[j].devno)
				&& (yx_define[j].info == buf[i * 7 + 15])) {
				temp_soe.status_switch_no =  j & 0xfff;
				if (buf[i * 7 + 16] & 0x01)
					temp_soe.status_switch_no |= 0x8000;
				else temp_soe.status_switch_no &= 0x7fff;	// 0x80:0->1  0x00:1->0

				GetClock(&sclk);
				temp = ((buf[i * 7 + 14] << 8) & 0xff00) + buf[i * 7 + 13];
			temp_soe.day = sclk.day;
			temp_soe.hour = buf[i * 7 + 10];
			temp_soe.minute = buf[i * 7 + 11];
			temp_soe.second = temp / 1000;
			temp_soe.msecond = temp % 1000;
				insert_soe(&temp_soe);
/*				temp_soe.time.date = (((sclk.year % 100) << 9) & 0xfe00) +
								((sclk.month << 5) & 0x01e0) + (sclk.day & 0x001f);
				temp_soe.time.time = ((sclk.weekday << 12) & 0xf000) +
								((buf[i * 7 + 10] << 7) & 0x0f80) + (buf[i * 7 + 11] & 0x007f);
				temp_soe.time.msec = ((buf[i * 7 + 12] << 10) & 0xfc00) +
								(temp & 0x03ff);
				insert_soe(&temp_soe);							// add to soe buffer*/
			}
		}
	}
}

INT16U CLfp::checksum(INT8U *buf, int len)
{
	 int i;
	 INT16U result = 0;

	 for (i = 0; i < len; i++) result += buf[i];
	 return(result);
}

void CLfp::process_message(INT8U *buf)
{
	if (buf[5] == send_add) rece_end = 1;
	switch (buf[6]) {
		case LFP_ACK:
			process_ack(buf);
			break;
		case LFP_NAK:
			process_nak(buf);
			break;
		case LFP_R10:
			process_R10(buf);
			send_ack_flag = TRUE;
			break;
		case LFP_R15:
			process_R15(buf);
			break;
		case LFP_R17:
			process_R17(buf);
			break;
		case LFP_R18:
			process_R18(buf);
			break;
		case LFP_R19:
			process_R19(buf);
			break;
		case LFP_R20:
			process_R20(buf);
			send_ack_flag = TRUE;
			break;
	}
}

void CLfp::master_receive()
{
	INT16U temp, rece_len, framelen;

	rece_len = get_com_rece_num(myportno);

	if (rece_len < 10) return; // too little
	get_com_rece_nbytes(recbuf, 10, myportno);

	if (recbuf[0] == 0xeb && recbuf[1] == 0x90 && recbuf[2] == 0xeb
		&& recbuf[3] == 0x90 && recbuf[4] == 0x02 && recbuf[5] == send_add) {
		framelen = recbuf[9] + 9;
		if (rece_len >= framelen) {
			read_com_rece_nbytes(recbuf, framelen, myportno);
			if (recbuf[framelen - 1] == 0x03) {
				temp = checksum(&recbuf[5], framelen - 8);
				if (((temp & 0xff) == recbuf[framelen - 3]) &&
					(((temp >> 8) & 0xff) == recbuf[framelen - 2])) {
					draw_rece_message(myportno, recbuf, framelen, POLL_RECE_COLOR);
					process_message(recbuf);
				}
			}
		}
	}
	else del_com_rece_one(myportno);
}

void CLfp::master_send()
{
	int i;

	if (!is_port_yk_doing(myportno)) yk_flag = FALSE;

	if (yk_flag) return;

	if (send_ack_flag) {
		send_ack();
		send_ack_flag = FALSE;
		rece_end = 0;
		return;
	}

	if (send_nak_flag) {
		send_nak();
		send_nak_flag = FALSE;
		rece_end = 0;
		return;
	}

	if (port_yk_info.Y_PRESET) { //yk preset
		if (port_yk_info.yk_des == myportno ) {
			port_yk_info.Y_PRESET = FALSE;
			yk_flag = TRUE;
			send_yk_preset();
			send_add = port_yk_info.dev_no;
			rece_end = 2;
			return;
		}
	}

	if (port_yk_info.Y_EXEC) { //yk execute
		if (port_yk_info.yk_des == myportno) {
			port_yk_info.Y_EXEC = FALSE;
			yk_flag = FALSE;
			send_yk_exec();
			send_add = port_yk_info.dev_no;
			rece_end = 2;
			return;
		}
	}

	if (port_yk_info.Y_ESC) { //yk escape
		if (port_yk_info.yk_des == myportno) {
			port_yk_info.Y_ESC = FALSE;
			yk_flag = FALSE;
			send_yk_esc();
			send_add = port_yk_info.dev_no;
			rece_end = 2;
			return;
		}
	}

	if (send_cycle >= 4000) {
		for (i = start_add; i <= end_add; i++)
			send_state[i] = 0;
		send_cycle = 0;
	}

	if (send_cycle % 100 == 1) { // per 99 cycle once asdu6
		send_C8();
		send_cycle++;
		rece_end = 0;
		return;
	}

	switch (send_state[station_add]) {
		case 0:
			send_state[station_add] = 1;
			send_C19();
			send_add = station_add;
			rece_end = 2;
			break;
		case 1:
			send_state[station_add] = 2;
			send_C19();
			send_add = station_add;
			rece_end = 2;
			change_addr();
			break;
		case 2:
			send_C15();
			send_state[station_add] = 3;
			send_add = station_add;
			rece_end = 2;
			break;
		case 3:
			send_C20();
			send_state[station_add] = 2;
			send_add = station_add;
			rece_end = 2;
			change_addr();
			break;
	}
}

BOOLEAN CLfp::change_addr()
{
	if (++station_add > end_add) {
		station_add = start_add;
		send_cycle++;
		return TRUE;
	}
	return FALSE;
}

void CLfp::deal()
{
	master_receive();
	if (!port_free(myportno)) return;

	if (port_timeout[myportno] >= 10) { //10 = 0.5s
		if (rece_end == 1) {
			fail_count[send_add] = 0;
			LINK_flag[send_add] = 1;
		}
		else if (rece_end == 2) {
			if (fail_count[send_add] > 3) {
				LINK_flag[send_add] = 0;
				send_state[send_add] = 0;
			}
			else fail_count[send_add]++;
			clear_com_rece_buf(myportno);
		}
		master_send();
		port_timeout[myportno] = 0;
	}
}

⌨️ 快捷键说明

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