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

📄 process.cpp

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

// yx bw buffer used in nbb protocol
yxbw_buf_t yxbw_buf;

// soe buffer for each port
soe_buf_t soe_buf;

// store collect infomation
memdb_data_t dbdata;

void rtdbmsinit(void)
{
	memset(&dbdata, 0, sizeof(memdb_data_t));
}

// single write pointer and multi read pointer
void insert_soe(soe_record_t *ptr)
{
	int i;

	OS_ENTER_CRITICAL();

	memcpy(&soe_buf.buf[soe_buf.write], ptr, sizeof(soe_record_t));
	soe_buf.write++;
	if (soe_buf.write >= YXBW_BUF_SIZE) soe_buf.write = 0;
	// write pointer out of boundary

	for (i = 0; i < MAX_PORT; i++) {
		if (soe_buf.count[i] >= YXBW_BUF_SIZE) {	// buffer overflow
			soe_buf.read[i]++;
			if (soe_buf.read[i] >= YXBW_BUF_SIZE)	// drop lastest one
				soe_buf.read[i] = 0;
		}
		else soe_buf.count[i]++;
	}
	OS_EXIT_CRITICAL();
}

// judge having soe or not
BOOLEAN is_soe(INT8U portno)
{
	if (soe_buf.count[portno] == 0)	return (FALSE);
	else return (TRUE);
}

// get a soe from soe queue
void get_soe(INT8U portno, soe_record_t *ptr)
{
	if (portno >= MAX_PORT) return; // only SLAVE protocol have soe
	OS_ENTER_CRITICAL();
	if (soe_buf.count[portno] > 0) {
		memcpy(ptr, &soe_buf.buf[soe_buf.read[portno]], sizeof(soe_record_t));
		soe_buf.read[portno]++;
		soe_buf.count[portno]--;                  // decrease soe amount

		if (soe_buf.read[portno] >= YXBW_BUF_SIZE)
			soe_buf.read[portno] = 0;						// read pointer out of boundary
	}
	OS_EXIT_CRITICAL();
}

INT16U get_soe_num(INT8U portno)
{
	return (soe_buf.count[portno]);
}

INT16U get_yx_bw_num(INT8U portno)
{
	return (yxbw_buf.count[portno]);
}

// insert a yxbw to yxbw queue
// new one overwrite old one
void insert_yx_bw(yxbw_record_t *ptr)
{
	int i;

	OS_ENTER_CRITICAL();

	memcpy(&yxbw_buf.buf[yxbw_buf.write], ptr, sizeof(yxbw_record_t));
	yxbw_buf.write++;
	if (yxbw_buf.write >= YXBW_BUF_SIZE) yxbw_buf.write = 0;
	// write pointer out of boundary

	for (i = 0; i < MAX_PORT; i++) {
		if (yxbw_buf.count[i] >= YXBW_BUF_SIZE) {	// buffer overflow
			yxbw_buf.read[i]++;
			if (yxbw_buf.read[i] >= YXBW_BUF_SIZE)	// drop lastest one
				yxbw_buf.read[i] = 0;
		}
		else yxbw_buf.count[i]++;
	}

	OS_EXIT_CRITICAL();
}

// judge having yxbw or not
BOOLEAN is_yx_bw(INT8U portno)
{
	if (yxbw_buf.count[portno] == 0)	return (FALSE);
	else return (TRUE);
}

// get a yxbw from yxbw queue
void get_yx_bw(INT8U portno, yxbw_record_t *ptr)
{
	if (portno >= MAX_PORT) return; // only SLAVE protocol have soe
	OS_ENTER_CRITICAL();
	if (yxbw_buf.count[portno] > 0) {
		memcpy(ptr, &yxbw_buf.buf[yxbw_buf.read[portno]], sizeof(yxbw_record_t));
		yxbw_buf.read[portno]++;
		yxbw_buf.count[portno]--;                  // decrease soe amount

		if (yxbw_buf.read[portno] >= YXBW_BUF_SIZE)
			yxbw_buf.read[portno] = 0;						// read pointer out of boundary
	}
	OS_EXIT_CRITICAL();
}

void CCaculate::init()
{
#ifdef CAL_GEAR
	init_ma_to_b_gear();
#endif
}

void CCaculate::init_ma_to_b_gear()
{
	FILE *fp;
	char buf[MAXFILEBUF];

	if ((fp = fopen("matogear.cfg", "rt")) == NULL) {
		return;
	}

	for (int i = 0; i < MA_TO_B_NUM; i++) {
		fgets(buf, MAXFILEBUF, fp);
		sscanf(buf, "%*s%*s%u", &ma_yc_no[i]);
	}

	fclose(fp);
	ma_timer = 0;
	memset(&current_gear[0], 0, sizeof(current_gear));
	ma_to_gear_first = TRUE;
}

void CCaculate::ma_to_b_gear() // 4-20mA current to 17 trasform gear
{
	INT16U range[18] = {358, 460, 562, 664, 766, 868, 970, 1072, 1174, 1276,
											1378, 1480, 1582, 1684, 1786, 1888, 1990, 2092};
	INT16U bvalue;
	int gear;
	int i, j, temp;
	soe_record_t temp_soe;
	yxbw_record_t temp_yx_bw;
	sclock sclk;

	if (ma_timer < 2) {
		ma_timer++;
		return;
	}
	else ma_timer = 0;

	for (i = 0; i < MA_TO_B_NUM; i++) {
		bvalue = dbdata.Yc[ma_yc_no[i]];
		if ((bvalue < 0x800) || (bvalue > 0xf00)) continue;
		bvalue = 0xfff - bvalue;
		for (j = 0; j < 17; j++)
			if (bvalue > range[j] && bvalue < range[j + 1]) {
				gear = j + 1;
				break;
			}

		if (ma_to_gear_first) {
			for (j = 0; j < _TotalYx; j++) {
				if (YxDefine[j].portno == 40 && YxDefine[j].type == i
					&& YxDefine[j].info == gear) {
					yx_update_db(j, 1);
					current_gear[i] = gear;
				}
			}
			ma_to_gear_first = FALSE;
			return;
		}

		if (gear == current_gear[i]) continue;

		for (j = 0; j < _TotalYx; j++) {
			if (YxDefine[j].portno == 40 && YxDefine[j].type == i
				&& YxDefine[j].info == current_gear[i]) {
				yx_update_db(j, 0);
				temp_soe.status_switch_no = j & 0xfff;
				temp_soe.status_switch_no &= 0x7fff;	// 0x80:0->1  0x00:1->0

				GetClock(&sclk);
				temp_soe.day = sclk.day;
				temp_soe.hour = sclk.hour;
				temp_soe.minute = sclk.minute;
				temp_soe.second = sclk.second;
				temp_soe.msecond = sclk.msecond;

				insert_soe(&temp_soe);						// add to soe buffer
				temp = (temp_soe.status_switch_no & 0xfff) / 32;
				temp_yx_bw.func_code = temp;
				temp_yx_bw.yx_code[0] = dbdata.Yx[temp * 2];
				temp_yx_bw.yx_code[1] = dbdata.Yx[temp * 2 + 1];
				insert_yx_bw(&temp_yx_bw);							// add to yx bw buffer
			}
			if (YxDefine[j].portno == 40 && YxDefine[j].type == i
				&& YxDefine[j].info == gear) {
				yx_update_db(j, 1);
				temp_soe.status_switch_no = j & 0xfff;
				temp_soe.status_switch_no |= 0x8000;	// 0x80:0->1  0x00:1->0

				GetClock(&sclk);
				temp_soe.day = sclk.day;
				temp_soe.hour = sclk.hour;
				temp_soe.minute = sclk.minute;
				temp_soe.second = sclk.second;
        temp_soe.msecond = sclk.msecond;
				insert_soe(&temp_soe);						// add to soe buffer
				temp = (temp_soe.status_switch_no & 0xfff) / 32;
				temp_yx_bw.func_code = temp;
				temp_yx_bw.yx_code[0] = dbdata.Yx[temp * 2];
				temp_yx_bw.yx_code[1] = dbdata.Yx[temp * 2 + 1];
				insert_yx_bw(&temp_yx_bw);							// add to yx bw buffer
			}
		}
		current_gear[i] = gear;
	}
}

void CCaculate::reset_protect_yx()
{
	int i, temp;
	soe_record_t temp_soe;
	yxbw_record_t temp_yx_bw;
	sclock sclk;

	for (i = 0; i < _TotalYx; i++) {
		if (YxDefine[i].reset != 0) {
			if (PR_start_flag[i]) { // wait reset
				if (PR_timer[i] > PROTECT_RESET_GAP) { // reach the reset time
					yx_update_db(i, 0);
					PR_start_flag[i] = FALSE;
					temp_soe.status_switch_no = i & 0xfff;
					temp_soe.status_switch_no &= 0x7fff;	// 0x80:0->1  0x00:1->0

					GetClock(&sclk);
					temp_soe.day = sclk.day;
					temp_soe.hour = sclk.hour;
					temp_soe.minute = sclk.minute;
					temp_soe.second = sclk.second;
					temp_soe.msecond = sclk.msecond;

					insert_soe(&temp_soe);						// add to soe buffer
					temp = (temp_soe.status_switch_no & 0xfff) / 32;
					temp_yx_bw.func_code = temp;
					temp_yx_bw.yx_code[0] = dbdata.Yx[temp * 2];
					temp_yx_bw.yx_code[1] = dbdata.Yx[temp * 2 + 1];
					insert_yx_bw(&temp_yx_bw);							// add to yx bw buffer
				}
				else PR_timer[i]++;
			}
			else { // detect reset
				if (get_yx_dot(i)) { // act
					PR_start_flag[i] = TRUE;
					PR_timer[i] = 0;
				}
			}
		}
	}
}

void CCaculate::deal()
{
#ifdef CAL_GEAR
	ma_to_b_gear();
#endif
	reset_protect_yx();
}

⌨️ 快捷键说明

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