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

📄 stmodbus.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 CSTModbus::READ_DI = 0x01;
const INT8U CSTModbus::READ_WORD = 0x03;
const INT8U CSTModbus::SET_COIL = 0x05;

CSTModbus::CSTModbus(INT8U portno):CMasterPollingProtocol(portno)
{
	SetQueryGap(1000);
	send_cycle = 0;
}

void CSTModbus::processREAD_DI(INT8U *buf)
{
	INT8U temp = 0;
	INT8U index = 0;
	INT8U bitno = 0;

	YxDefine_t *pyx = NULL;

	for (int i = 0; i < yx_num; i++) {
		pyx = GetYxDefine(pyx_tbl[i]);

		if ((pyx->devno == buf[0]) && (pyx->info <= 0x1b)) {
			index = pyx->info / 8;
			bitno = pyx->info % 8;
			temp = (buf[3 + index] >> bitno) & 0x01;

			ProtocolProcessYX(pyx_tbl[i], temp);
		}
	}
}

void CSTModbus::processREAD_WORD(INT8U *buf)
{
	int temp = 0;
	YcDefine_t *pyc = NULL;

	for (int i = 0; i < yc_num; i++) {
		pyc = GetYcDefine(pyc_tbl[i]);

		if((pyc->devno == buf[0]) && (pyc->info <= 0x13)) {
			temp = (buf[pyc->info * 2 + 3] << 8) + buf[pyc->info * 2 + 4];
			yc_update_db(pyc_tbl[i], temp);
		}
	}
}

void CSTModbus::send_yx()
{
	INT16U temp;
	INT8U askbuf[8];

	askbuf[0] = CurrentQueryAddr;
	askbuf[1] = READ_DI;
	askbuf[2] = 0x00;
	askbuf[3] = 0x00;

	askbuf[4] = 0x00;
	askbuf[5] = 0x1c; //total yx is 0x1c

	temp = get_crc16_code(askbuf, 6);
	askbuf[6] = (temp >> 8) & 0xff;
	askbuf[7] = temp & 0xff;

	QueryStatus = QUERY;

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

void CSTModbus::send_yc()
{
	INT16U temp;
	INT8U askbuf[8];

	askbuf[0] = CurrentQueryAddr;
	askbuf[1] = READ_WORD;
	askbuf[2] = 0x00;
	askbuf[3] = 0x00;

	askbuf[4] = 0x00;
	askbuf[5] = 0x13; //total yc is 0x13

	temp = get_crc16_code(askbuf, 6);
	askbuf[6] = (temp >> 8) & 0xff;
	askbuf[7] = temp & 0xff;

	QueryStatus = QUERY;

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

void CSTModbus::send_yk()
{
	INT16U temp;
	INT8U askbuf[8];

	askbuf[0] = port_yk_info.dev_no;
	askbuf[1] = SET_COIL;
	askbuf[2] = 0x00; // high address
	askbuf[3] = port_yk_info.yk_no; // low address

	if (port_yk_info.yk_cmd == YKCTRIP) {
		askbuf[4] = 0x00;
	}
	else if (port_yk_info.yk_cmd == YKCCLOSE){
		askbuf[4] = 0xff;
	}
	askbuf[5] = 0x00; // control command 0xff00 close/0x0000 open

	temp = get_crc16_code(askbuf, 6);
	askbuf[6] = (temp >> 8) & 0xff;
	askbuf[7] = temp & 0xff;

	QueryStatus = QUERY;

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

void CSTModbus::PreProcess()
{
	if (port_yk_info.Y_PRESET) { //yk preset
		if (port_yk_info.yk_des == myportno) {
			port_yk_info.Y_PRESET = FALSE;
			port_yk_info.Y_CHECK = TRUE;
			port_yk_info.check_result = YKROK;
			return;
		}
	}
}

void CSTModbus::master_send()
{
	if (port_yk_info.Y_EXEC) { //yk execute
		if (port_yk_info.yk_des == myportno) {
			port_yk_info.Y_EXEC = FALSE;
			send_yk();
			QueryStatus = BOARDCAST;
			return;
		}
	}

	if (port_yk_info.Y_ESC) { //yk escape
		if (port_yk_info.yk_des == myportno) {
			port_yk_info.Y_ESC = FALSE;
			return;
		}
	}

	if (send_cycle++ % 2) {
		if (++CurrentQueryAddr>DevEndAddr) CurrentQueryAddr = DevStartAddr;
		send_yx();
	}
	else {
		send_yc();
	}
}

void CSTModbus::process(INT8U *buf)
{
	switch (buf[1]) {
		case READ_DI:
			processREAD_DI(buf);
			break;
		case READ_WORD:
			processREAD_WORD(buf);
			break;
	}
}

void CSTModbus::master_receive()
{
	INT16U temp = 0;
	INT8U recbuf[MODBUS_RECE_BUFSIZE];
	INT16U rece_len = get_com_rece_num(myportno);

	if (rece_len < 5) return;
	get_com_rece_nbytes(&recbuf[0], 5, myportno);

	if (recbuf[0] != CurrentQueryAddr) {
		del_com_rece_one(myportno);
		return;
	}

	if (recbuf[1] == 0x05) { // yk command
		if (rece_len >= 8) {
			read_com_rece_nbytes(&recbuf[0], 8, myportno);
			draw_rece_message(myportno, &recbuf[0], 8, POLL_RECE_COLOR);
			temp = get_crc16_code(&recbuf[0], 6);
			if (temp == ((recbuf[6] << 8) | recbuf[7])) { // crc ok
				process(&recbuf[0]);
				QueryStatus = ANSWER;
			}
		}
	}
	else { // not yk
		INT16U framelen = recbuf[2] + 5;
		if (rece_len >= framelen) {
			read_com_rece_nbytes(&recbuf[0], framelen, myportno);
			draw_rece_message(myportno, &recbuf[0], framelen, POLL_RECE_COLOR);
			temp = get_crc16_code(&recbuf[0], framelen - 2);
			if (temp == ((recbuf[framelen - 2] << 8) | recbuf[framelen - 1])) {
				process(&recbuf[0]);
				QueryStatus = ANSWER;
			}
		}
	}
}

⌨️ 快捷键说明

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