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

📄 comclass.cpp

📁 基于PC104平台
💻 CPP
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                 File name: comclass.cpp
//  This file define the functions used in seriel communication
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "comclass.h"

void portparset(BYTE portno)
{
  BYTE baudrate_code;
  BYTE parity;
  BYTE stop;
  BYTE databits_code;
  unsigned int divisor;
  unsigned int lsb,msb;
  long unsigned int baudrate;
  unsigned int port_address;
  unsigned int parmbyte;
  int databits;

	switch (portno) {
		case COM1:
			port_address = 0x3f8;
			baudrate_code = port_set[COM1].BaudRate;
			databits_code = port_set[COM1].DataBits;
			stop = port_set[COM1].StopBits;
			parity = port_set[COM1].Parity;
			break;
		case COM2:
			port_address = 0x2f8;
			baudrate_code = port_set[COM2].BaudRate;
			databits_code = port_set[COM2].DataBits;
			stop = port_set[COM2].StopBits;
			parity = port_set[COM2].Parity;
			break;
		case PORT1:
		case PORT2:
		case PORT3:
		case PORT4:
		case PORT5:   
		case PORT6:
		case PORT7:
		case PORT8:
			port_address = hardwareset[portno / 4].address + (portno - portno / 4 * 4) * 8;
			baudrate_code = port_set[portno].BaudRate;
			databits_code = port_set[portno].DataBits;
			stop = port_set[portno].StopBits;
			parity = port_set[portno].Parity;
			break;
	}

	switch (baudrate_code) {
		case B50:	  baudrate=50;	 break;
		case B75:	  baudrate=75;	 break;
		case B110: 	  baudrate=110;  break;
		case B134: 	  baudrate=134;  break;
		case B150: 	  baudrate=150;  break;
		case B300: 	  baudrate=300;  break;
		case B600: 	  baudrate=600;  break;
		case B1200:	  baudrate=1200; break;
		case B1800:	  baudrate=1800; break;
		case B2400:	  baudrate=2400; break;
		case B4800:	  baudrate=4800; break;
		case B7200:	  baudrate=7200; break;
		case B9600:	  baudrate=9600; break;
		case B19200:      baudrate=19200; break;
		case B38400:      baudrate=38400; break;
		case B57600:      baudrate=57600; break;
		case B115200:     baudrate=115200; break;
	}

	divisor = 115200 / baudrate;
	msb = (divisor >> 8) & 0xff;
	divisor = 115200 / baudrate;
	lsb = divisor & 0xff;
	outportb(port_address + 3, 0x80);//enable
	outportb(port_address, lsb);
	outportb(port_address + 1, msb);
	//above is for set baudrate
	switch (databits_code) {
		case BIT_5:	 databits = 5;	 break;
		case BIT_6:	 databits = 6;	 break;
		case BIT_7:	 databits = 7;	 break;
		case BIT_8:	 databits = 8;	 break;
	}

	parmbyte = databits - 5;
	if (stop == STOP_2)        parmbyte |= 0x04; //LCONT_STOP;
	if (parity != PARITY_NONE) parmbyte |= 0x08; //0x00;LCONT_PARITY_ENABLE;
	if (parity == PARITY_EVEN) parmbyte |= 0x10; //LCONT_PARITY_SELECT;

	outportb(port_address + 3, parmbyte);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
void bufinit()
{
	int i;

	for (i = 0; i < 10; i++) {
		inring[i].count = 0;
		inring[i].start = 0;
		inring[i].cnext = 0;
		inring[i].size = RINGSIZE;
	}

	outring.count = 0;
	outring.start = 0;
	outring.cnext = 0;
	outring.size = RINGSIZE;
}

void put_in(INT8U data, INT8U portno)
{
	inring[portno].buffer[inring[portno].cnext] = data;
	inring[portno].cnext++;
	if (inring[portno].cnext >= inring[portno].size) {
		inring[portno].cnext = 0;
		if (inring[portno].start == inring[portno].cnext)
			inring[portno].start++;
	}
	inring[portno].count++;
	if (inring[portno].count >= inring[portno].size) //overflow?
		inring[portno].count--;
}

BOOLEAN get_in(BYTE portno)
{
  if(inring[portno].count<=0)//nothing there
	  return(FALSE);
  getchin[portno]=inring[portno].buffer[inring[portno].start];
  inring[portno].count--;//update count of retrievable chars
  inring[portno].start++;
  if(inring[portno].start>=inring[portno].size)
	  inring[portno].start-=inring[portno].size;
  return(TRUE);
}//BOOLEAN get_in(BYTE portno)
////////////////////////////////////////////////////////////////////////////////////////////////////////
void interrupt inthandcom1(...)
{
   disable();
   while((inportb(0x3fd))&0x01)put_in(inportb(0x3f8),COM1);
   outportb(0x20,0x20); //end of interrupt to first PIC
   enable();
}//void interrupt inthandcom1(...)

void interrupt inthandcom2(...)
{
   disable();
   while((inportb(0x2fd))&0x01)put_in(inportb(0x2f8),COM2);
   outportb(0x20,0x20); //end of interrupt to first PIC
   enable();
}//void interrupt inthandcom2(...)

void initcom1()
{
  BYTE oldval;
  BYTE picmask;
  disable();
  oldhandcom1=getvect(0x0c);
  setvect(0x0c,inthandcom1);
  outportb(0x3fc,0x0f);
  inportb(0x3fe);
  inportb(0x3fd);
  (void)inportb(0x3f8);
  (void)inportb(0x3fa);
  outportb(0x3fa,0xc7);//14 byte
  outportb(0x3f9,0x01);//enable interrupts on the UART
  picmask=1<<(4%8);
  _asm cli  //read the PIC interrupt enable
  oldval=inportb(0x21);
  outportb(0x21,oldval&!picmask);
  _asm sti
  outportb(0x20,0x20);//reset the PIC
  enable();
  portparset(COM1);
}//void initcom1()

void initcom2()
{
  unsigned int oldval;
  unsigned int picmask;
  disable();
  oldhandcom2=getvect(0x0b);
  setvect(0x0b,inthandcom2);
  outportb(0x2fc,0x0f);
  inportb(0x2fe);
  inportb(0x2fd);
  (void)inportb(0x2f8);
  (void)inportb(0x2fa);
  outportb(0x2fa,0xc7);//14 byte
  outportb(0x2f9,0x01);//enable interrupts on the UART  //in
  //outportb(0x2f9,0x03);//enable interrupts on the UART  //in and out
  //outportb(0x2f9,0x02);//enable interrupts on the UART    //out
  picmask=1<<(3%8);
  _asm cli  //read the PIC interrupt enable
  oldval=inportb(0x21);
  outportb(0x21,oldval&!picmask);
  _asm sti
  outportb(0x20,0x20);//reset the PIC
  enable();
  portparset(COM2);
}//void initcom2()

void interrupt Moxa1int(...)
{
	INT16U base;
	asm cli;
	base = hardwareset[C36401].address;
	while (inportb(base + 0x05) & 0x01)
		put_in(inportb(base + 0x00), PORT1);

	while (inportb(base + 0x0d) & 0x01)
		put_in(inportb(base + 0x08), PORT2);

	while (inportb(base + 0x15) & 0x01)
		put_in(inportb(base + 0x10), PORT3);

	while (inportb(base + 0x1d) & 0x01)
		put_in(inportb(base + 0x18), PORT4);

	outportb(0x20, 0x20);//reset the PIC2
	outportb(0xa0, 0x20);//reset the PIC2

	asm sti;
}

void interrupt Moxa2int(...)
{
	INT16U base;
	asm cli;
	base = hardwareset[C36402].address;
	while (inportb(base + 0x05) & 0x01)
		put_in(inportb(base + 0x00), PORT5);

	while (inportb(base + 0x0d) & 0x01)
		put_in(inportb(base + 0x08), PORT6);  

	while (inportb(base + 0x15) & 0x01)
		put_in(inportb(base + 0x10), PORT7);

	while (inportb(base + 0x1d) & 0x01)
		put_in(inportb(base + 0x18), PORT8);

	outportb(0x20, 0x20);
	outportb(0xa0, 0x20);

	asm sti;
}

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

	asm cli;
	Moxa1OldHand = getvect(hardwareset[C36401].intno + 0x68);
	setvect(hardwareset[C36401].intno + 0x68, Moxa1int);

	for (i = 0; i < 4; i++) {
		base = hardwareset[C36401].address + i * 8;
		outportb(base + 0x04, 0x0f); // modem control register
		inportb(base + 0x05);
		inportb(base + 0x06);
		inportb(base);
		inportb(base + 0x02);
		outportb(base + 0x02, 0xc7); // rx trigger level 14byte in FIFO
		outportb(base + 0x01, 0x01); // enable interrupts on the UART
	}

	picmask = 1 << (hardwareset[C36401].intno % 8);
	oldval = inportb(0x21);
	outportb(0x21, oldval & 0xfb);
	oldval = inportb(0xa1);
	outportb(0xa1, oldval & !picmask);
	outportb(0x20, 0x20);
	outportb(0xa0, 0x20);

	asm sti;
	for (i = PORT1; i <= PORT4; i++) portparset(i);
}

void ResetMoxa1()
{
	INT8U oldval, picmask;

	asm cli;
	setvect(hardwareset[C36401].intno + 0x68, Moxa1OldHand);

	picmask = 1 << (hardwareset[C36401].intno % 8);
	oldval = inportb(0xa1);
	outportb(0xa1, oldval | picmask);
	outportb(0x20, 0x20);
	outportb(0xa0, 0x20);

	asm sti;
}

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

	asm cli;
	Moxa2OldHand = getvect(hardwareset[C36402].intno + 0x68);
	setvect(hardwareset[C36402].intno + 0x68, Moxa2int);

	for (i = 0; i < 4; i++) {
		base = hardwareset[C36402].address + i * 8;
		outportb(base + 0x04, 0x0f); // modem control register
		inportb(base + 0x05);
		inportb(base + 0x06);
		inportb(base);
		inportb(base + 0x02);
		outportb(base + 0x02, 0xc7); // rx trigger level 14byte in FIFO
		outportb(base + 0x01, 0x01); // enable interrupts on the UART
	}

	picmask = 1 << (hardwareset[C36402].intno % 8);
	oldval = inportb(0x21);
	outportb(0x21, oldval & 0xfb);
	oldval = inportb(0xa1);
	outportb(0xa1, oldval & !picmask);
	outportb(0x20, 0x20);
	outportb(0xa0, 0x20);

	asm sti;
	for(i = PORT5; i <= PORT8; i++) portparset(i);  
}

void ResetMoxa2()
{
	INT8U oldval, picmask;

	asm cli;
	setvect(hardwareset[C36402].intno + 0x68, Moxa2OldHand);

	picmask = 1 << (hardwareset[C36402].intno % 8);
	oldval = inportb(0xa1);
	outportb(0xa1, oldval | picmask);
	outportb(0x20, 0x20);
	outportb(0xa0, 0x20);

	asm sti;
}

void CommInit()
{
	bufinit();
    initcom1();
	initcom2();
}

void ResetComm()
{
}

BOOLEAN port_free(BYTE portno)
{
	INT16U base;
	switch (portno) {
		case COM1:	 base = 0x3fd;	 break;
		case COM2:	 base = 0x2fd;	 break;
		case PORT1:
		case PORT2:
		case PORT3:
		case PORT4:
		case PORT5:  
		case PORT6:
		case PORT7:
		case PORT8:
			base = hardwareset[portno / 4].address + (portno - portno / 4 * 4) * 8 + 0x05;
			break;
	}
	if (inportb(base) & 0x20) return(TRUE);
	else return(FALSE);
}

void comput_tx(BYTE portno)
{
	int value;
	unsigned int port_address;
  switch(portno)
  {
	 case COM1:	 port_address=0x3f8;	 break;
	 case COM2:	 port_address=0x2f8;	 break;
	 case PORT1:    case PORT2:    case PORT3:    case PORT4:
	 case PORT5:    case PORT6:    case PORT7:    case PORT8:  
	 port_address=hardwareset[portno/4].address+(portno-portno/4*4)*8;
	 break;
  }//switch(portno)
  if((Tx_data[portno][12]==12)||(quick_send==TRUE))
  {
    for(int i=0;i<Tx_data[portno][12];i++)
    {
      value=Tx_data[portno][i];
		_asm mov ax,value
      _asm mov dx,port_address
      _asm out dx,al
    }//for(int i=0;i<Tx_data[portno][12];i++)
    Tx_data[portno][12]=0;
	 if(quick_send==TRUE)quick_send=FALSE;
  }//if((Tx_data[portno][12]==12)||(quick_send==TRUE))
}//void comput_tx(BYTE portno)
////////////////////////////////////////////////////////////////////////////////////////////////////////
void comput(BYTE value,BYTE portno)
{
  if(Tx_data[portno][12]<12)
  {
    Tx_data[portno][Tx_data[portno][12]]=value&0xff;
    Tx_data[portno][12]++;
    if((Tx_data[portno][12]==12)||(quick_send==TRUE))comput_tx(portno);
    watchdog[portno]=0;
  }//if(Tx_data[portno][12]<12)
}//void comput(BYTE value,BYTE portno)
////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN get_in_protect(BYTE portno)
{
	if (protectbuf[portno].rcount <= 0)
		return (FALSE);
	getinprotect[portno] = protectbuf[portno].rbuf[protectbuf[portno].rstart];
	protectbuf[portno].rcount --;
	getinprotect[10] = protectbuf[portno].rcount;
	protectbuf[portno].rstart ++;
	if (protectbuf[portno].rcount >= protectbuf[portno].rsize)
		protectbuf[portno].rstart -= protectbuf[portno].rsize;
	return (TRUE);
}

⌨️ 快捷键说明

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