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

📄 comclass.cpp

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

rxring_t inring[MAX_PORT];
txring_t outring[MAX_PORT];

INT32U rx_count[MAX_PORT];
INT32U tx_count[MAX_PORT];

void interrupt (*Moxa1OldHand)(...);
void interrupt (*Moxa2OldHand)(...);
void interrupt Moxa1int(...);
void interrupt Moxa2int(...);

// set sio parameter
void ComParaSet(INT16U addr, INT16U baud,	INT8U databit, INT8U stopbit, INT8U parity);

// write rece sio data to buffer
void com_to_buf(INT8U data, INT8U portno);

// get rece buffer bytes
INT16U get_com_rece_num(INT8U portno);

// get nbytes from rece buffer not delete
INT16U get_com_rece_nbytes(INT8U *buf, INT16U len, INT8U portno);

// get nbytes from rece buf & delete
INT16U read_com_rece_nbytes(INT8U *buf, INT16U len, INT8U portno);

// delete one byte from rece buffer
void del_com_rece_one(INT8U portno);

// initial moxa card (1) reset moxa card (1)
void InitMoxa1(void);
void ResetMoxa1(void);

// initial moxa card (2) reset moxa card (2)
void InitMoxa2(void);
void ResetMoxa2(void);

// call bufinit() & set addr & set intno
void CommInit(void);

// write len bytes data to send buffer & sending
void com_transfer(INT8U portno, INT16U len, INT8U *buf);

// check port busy & not busy sending
BOOLEAN port_free(INT8U portno);

void ComParaSet(INT16U addr, INT16U baud,
								INT8U databit, INT8U stopbit, INT8U parity)
{
	INT16U divisor;
	INT8U parmbyte;

	divisor = 115200L / baud;

	outp(addr + 3, 0x80);//enable
	outp(addr, (INT8U)(divisor & 0xff));
	outp(addr + 1, (INT8U)(divisor >> 8));

	parmbyte = databit - 5;
	if (stopbit == 2) parmbyte |= 0x04;
	if (parity != 0) parmbyte |= 0x08; //none
	if (parity == 1) parmbyte |= 0x10; //even;

	outportb(addr + 3, parmbyte);
}

void com_to_buf(INT8U data, INT8U portno)
{
	if (inring[portno].count < inring[portno].size) {
		inring[portno].count++;
		rx_count[portno]++;

		inring[portno].buf[inring[portno].next] = data;
		if (++inring[portno].next >= inring[portno].size)
			inring[portno].next = 0;
	}
	else {
		if (++inring[portno].start >= inring[portno].size)
			inring[portno].start = 0;
		rx_count[portno]++;
		inring[portno].buf[inring[portno].next] = data;
		if (++inring[portno].next >= inring[portno].size)
			inring[portno].next = 0;
	}
}

INT16U get_com_rece_num(INT8U portno)
{
	INT16U count;

	OS_ENTER_CRITICAL();
	count = inring[portno].count;
	OS_EXIT_CRITICAL();

	return(count);
}

INT16U get_com_rece_nbytes(INT8U *buf, INT16U len, INT8U portno)
{
	int need_to_get;
	int count, start, size;
	int i;

	OS_ENTER_CRITICAL();
	count = inring[portno].count;
	start = inring[portno].start;
	size = inring[portno].size;
	OS_EXIT_CRITICAL();

	if (count >= len) need_to_get = len;
	else need_to_get = count;

	for (i = 0; i < need_to_get; i++) {
		buf[i] = inring[portno].buf[start];
		if (count > 0) {
			count--;
			start++;
			if (start >= size) start = 0;
		}
	}

	return (need_to_get);
}

INT16U read_com_rece_nbytes(INT8U *buf, INT16U len, INT8U portno)
{
	INT16U need_to_get;
	int i;

	OS_ENTER_CRITICAL();
	if (inring[portno].count >= len) need_to_get = len;
	else need_to_get = inring[portno].count;

	for (i = 0; i < need_to_get; i++) {
		buf[i] = inring[portno].buf[inring[portno].start];
		if (inring[portno].count > 0) {

			inring[portno].start++;
			if (inring[portno].start >= inring[portno].size)
				inring[portno].start = 0;
		}
	}
	inring[portno].count -= need_to_get;
	OS_EXIT_CRITICAL();

	return (need_to_get);
}

void del_com_rece_one(INT8U portno)
{
	OS_ENTER_CRITICAL();

	if (inring[portno].count > 0) {
		inring[portno].count--;
		inring[portno].start++;
		if (inring[portno].start >= inring[portno].size)
			inring[portno].start = 0;
	}

	OS_EXIT_CRITICAL();
}

void clear_com_rece_buf(INT8U portno)
{
	OS_ENTER_CRITICAL();
	inring[portno].count = 0;
	inring[portno].start = 0;
	inring[portno].next = 0;
	inring[portno].size = RX_COM_BUF_SIZE;
	OS_EXIT_CRITICAL();
}

void interrupt Moxa1int(...)
{
	int i;

	disable();

	for (i = 0; i < _sio1total; i++) {
		if (!PortSet[i].isReady || !PortSet[i].isWork)
			continue;
		while (inp(PortSet[i].BaseAddr + 0x05) & 0x01)
			com_to_buf(inp(PortSet[i].BaseAddr), i);
	}

	outp(0x20, 0x20);
	outp(0xa0, 0x20);
	enable();
}

void interrupt Moxa2int(...)
{
	int i;
	disable();

	for (i = _sio1total; i < _sio1total + _sio2total; i++) {
		if (!PortSet[i].isReady || !PortSet[i].isWork)
			continue;
		while (inp(PortSet[i].BaseAddr + 0x05) & 0x01)
			com_to_buf(inp(PortSet[i].BaseAddr), i);
	}

	outp(0x20, 0x20);
	outp(0xa0, 0x20);
	enable();
}

void InitMoxa1()
{
	INT8U oldval, picmask;
	INT16U i;

	if (_sio1int < 8 || _sio1int > 15) {
		perror("comm board1 interrupt error");
		exit(0);
	}

	if ((~CardStatusYx) & 1) return;

	disable();

	Moxa1OldHand = getvect(_sio1int + 0x68);
	setvect(_sio1int + 0x68, Moxa1int);

	for (i = 0; i < _sio1total; i++) {
		if (!PortSet[i].isReady || !PortSet[i].isWork)
			continue;
		outp(PortSet[i].BaseAddr + 0x04, 0x0f); // modem control register
		inp(PortSet[i].BaseAddr + 0x05);
		inp(PortSet[i].BaseAddr + 0x06);
		inp(PortSet[i].BaseAddr);
		inp(PortSet[i].BaseAddr + 0x02);
		outp(PortSet[i].BaseAddr + 0x02, 0xc7); // rx trigger level 14byte in FIFO
		outp(PortSet[i].BaseAddr + 0x01, 0x01); // enable interrupts on the UART
		ComParaSet(PortSet[i].BaseAddr, PortSet[i].Baud,
							PortSet[i].DataBit, PortSet[i].StopBit, PortSet[i].Parity);
	}

	picmask = 1 << (_sio1int % 8);
	oldval = inp(0x21);
	outp(0x21, oldval & 0xfb);
	oldval = inp(0xa1);
	outp(0xa1, oldval & ~picmask);
	outp(0x20, 0x20);
	outp(0xa0, 0x20);

	enable();
}

void ResetMoxa1(void)
{
	INT8U oldval, picmask;

	if ((~CardStatusYx) & 1) return;

	disable();
	setvect(_sio1int + 0x68, Moxa1OldHand);

	picmask = 1 << (_sio1int % 8);
	oldval = inp(0xa1);
	outp(0xa1, oldval | picmask);
	outp(0x20, 0x20);
	outp(0xa0, 0x20);

	enable();
}

void InitMoxa2(void)
{
	INT8U oldval, picmask;
	INT16U i;

	if (_sio2int < 8 || _sio2int > 15) {
		perror("comm board2 interrupt error");
		exit(0);
	}

	if ((~CardStatusYx) & 2) return;

	disable();

	Moxa2OldHand = getvect(_sio2int + 0x68);
	setvect(_sio2int + 0x68, Moxa2int);

	for (i = _sio1total; i < _sio1total + _sio2total; i++) {
		if (!PortSet[i].isReady || !PortSet[i].isWork)
			continue;

		outp(PortSet[i].BaseAddr + 0x04, 0x0f); // modem control register
		inp(PortSet[i].BaseAddr + 0x05);
		inp(PortSet[i].BaseAddr + 0x06);
		inp(PortSet[i].BaseAddr);
		inp(PortSet[i].BaseAddr + 0x02);
		outp(PortSet[i].BaseAddr + 0x02, 0xc7); // rx trigger level 14byte in FIFO
		outp(PortSet[i].BaseAddr + 0x01, 0x01); // enable interrupts on the UART
		ComParaSet(PortSet[i].BaseAddr, PortSet[i].Baud,
							PortSet[i].DataBit, PortSet[i].StopBit, PortSet[i].Parity);
	}

	picmask = 1 << (_sio2int % 8);
	oldval = inp(0x21);
	outp(0x21, oldval & 0xfb);
	oldval = inp(0xa1);
	outp(0xa1, oldval & ~picmask);

	outp(0x20, 0x20);
	outp(0xa0, 0x20);
	enable();
}

void ResetMoxa2(void)
{
	INT8U oldval, picmask;

	if ((~CardStatusYx) & 2) return; // sio2 not exist

	disable();
	setvect(_sio2int + 0x68, Moxa2OldHand);

	picmask = 1 << (_sio2int % 8);
	oldval = inp(0xa1);
	outp(0xa1, oldval | picmask);
	outp(0x20, 0x20);
	outp(0xa0, 0x20);

	enable();
}

void CommInit(void)
{
	int i, j;

	for (i = 0; i < MAX_PORT; i++) {
		inring[i].count = 0;
		inring[i].start = 0;
		inring[i].next = 0;
		inring[i].size = RX_COM_BUF_SIZE;

		outring[i].count = 0;
		outring[i].curptr = 0;
		outring[i].size = TX_COM_BUF_SIZE;
		outring[i].flaguse = FALSE;

		rx_count[i] = 0;
		tx_count[i] = 0;
	}

	for (i = 0; i < _sio1total; i++)
		PortSet[i].BaseAddr = _sio1base + i * 8;

	for (j = 0; j < _sio2total; j++)
		PortSet[i + j].BaseAddr = _sio2base + j * 8;
}

BOOLEAN port_free(INT8U portno)
{
	int i;

	if (inp(PortSet[portno].BaseAddr + 5) & 0x20) {

		if (outring[portno].flaguse == TRUE) {
			if ((outring[portno].count - outring[portno].curptr) < 12) {
				while (outring[portno].curptr < outring[portno].count) {
					outp(PortSet[portno].BaseAddr, outring[portno].buf[outring[portno].curptr]);
					outring[portno].curptr++;
					tx_count[portno]++;
				}
				outring[portno].flaguse = FALSE;
			}
			else {
				for (i = 0; i < 12; i++) {
					outp(PortSet[portno].BaseAddr, outring[portno].buf[outring[portno].curptr]);
					outring[portno].curptr++;
					tx_count[portno]++;
				}
			}
			return (FALSE);
		}
		else return (TRUE);
	}
	else return (FALSE);
}

void com_transfer(INT8U portno, INT16U len, INT8U *buf)
{
	int i;

	if (outring[portno].flaguse == TRUE) return;
	else {
		if (len > outring[portno].size) return;
		memcpy(outring[portno].buf, buf, len);
		outring[portno].count = len;
		outring[portno].curptr = 0;
		outring[portno].flaguse = TRUE;

		if (outring[portno].count <= 12) {
			for (i = 0; i < outring[portno].count; i++) {
				outp(PortSet[portno].BaseAddr, outring[portno].buf[outring[portno].curptr]);
				outring[portno].curptr++;
				tx_count[portno]++;
			}
			outring[portno].flaguse = FALSE;
		}
		else {
			for (i = 0; i< 12; i++) {
				outp(PortSet[portno].BaseAddr, outring[portno].buf[outring[portno].curptr]);
				outring[portno].curptr++;
				tx_count[portno]++;
			}
		}
	}
}

⌨️ 快捷键说明

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