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

📄 serial.c

📁 zywSERIAL.rar是16c554接口芯片驱动程序
💻 C
字号:
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

#define ST16C654   0x00
#define TL16C554   0x01

#define USE_COMMUNICATION_CHIP  ST16C654



#ifdef carddebug
unsigned char _______[0x400];
#define  _inportb(a)      (_______[a])
#define  _outportb(a,b)   (_______[a]=b)
#else
#define  _inportb(a)      (inportb(a))
#define  _outportb(a,b)   (outportb(a,b))
#endif

#define RS485               0x0001
#define RS232               0x0000

#define CANNOT_ALLOC_MEMORY 0x0002

#define SUCCESS             0x0000
#define PORT_NOT_OPENED     0x0001

#define PORT_SUCCESS_OPEN   0x0000
#define PORT_ALREADY_OPEN   0x0001
#define PORT_CANNOT_OPEN    0x0002

#define PORT_SUCCESS_CLOSE  0x0000
#define PORT_ALREADY_CLOSE  0x0001
#define PORT_CANNOT_CLOSE   0x0002

#define PORT_ALWAY_OPENED   0x0001
#define IO_OVER             0x0002

#define DEFAULT_SIZE        256



#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif

#define _RHR  0x00   //只读
#define _THR  0x00   //只写
#define _IER  0x01   //读写
#define _IIR  0x02   //只读
#define _FCR  0x02   //只写
#define _LCR  0x03   //读写
#define _MCR  0x04   //读写
#define _LSR  0x05   //读写
#define _MSR  0x06   //读写
#define _STR  0x07   //读写
#define _LSB  0x00   //读写
#define _MSB  0x01   //读写

typedef struct
{
	unsigned char RHR ;   
	unsigned char THR ;   
	unsigned char IER ;  
	unsigned char IIR ;   
	unsigned char FCR ;   
	unsigned char LCR ;   
	unsigned char MCR ;   
	unsigned char LSR ;   
	unsigned char MSR ;  
	unsigned char STR ;   
	unsigned char LSB ;   
	unsigned char MSB ;   
}
_tl16c550b_reg;

enum baud_enum     {B300=0,B600=1,B900=2,B1200=3,B2400=4,B4800=5,B9600=6,B19200=7,B38400=8,B57600=9,B115200=10};
enum parity_enum   {None=0,Odd=1,Even=3,Mark=5,Space=7};
enum databit_enum  {D5=0,D6=1,D7=2,D8=3};
enum stop_enum     {ST1=0,ST2=1};
enum fifo_enum     {B1=0,B4=1,B8=2,B14=3};

typedef struct
{

	unsigned int     ba;                     
	unsigned int     baud;
	unsigned char      parity;
	unsigned char      databit;
	unsigned char      stop;
	int     mode;                  
	_tl16c550b_reg   r;                      //串口硬件寄存器
	unsigned char      fifo;
	int     r_size;                
	int     t_size;                 
	unsigned char     r_buf_h;                //接收缓冲区头指针
	unsigned char     t_buf_h;                //发送缓冲区头指针
	unsigned char     r_buf_t;                //接收缓冲区尾指针
	unsigned char     t_buf_t;                //发送缓冲区尾指针
	unsigned char      r_buf[256];                 //接收缓冲区
	unsigned char      t_buf[256];                 //发送缓冲区

}tl16c550b;

tl16c550b pt[8];

unsigned int rece_led,send_led;
unsigned int fff_e[8],fff_r[8];

void interrupt (*irq_old)(__CPPARGS);
void interrupt irq9(__CPPARGS);

void dint_r(unsigned int);
void dint_t(unsigned int);
void eint_r(unsigned int);
void eint_t(unsigned int);

void high_rts(unsigned int);
void low_rts(unsigned int);

int isopened(unsigned int);
int closeport(int com);
int openport(int com, unsigned int _baud, unsigned char _parity, unsigned char _databit, unsigned char _stop);
int getabyte(int com);
int putabyte(int com, unsigned char c);
int read_data(unsigned int c, unsigned char *dest_buf);
int send_data(unsigned int c, unsigned char *source_buf, int l);
int set_parity(int com, unsigned char parity);
int set_mode(int com, int mode);
int receive_count(int com);
int send_buf_count(int c);

void opt(struct REGPACK*);
void CommunicationCardSetVector(int,void interrupt (*)(__CPPARGS));
void interrupt (*Excute)(__CPPARGS);

const unsigned int intflag[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
	
void interrupt Nullinterrupt(__CPPARGS)
{}

int send_buf_count(int c)
{
	if(pt[c].t_buf_t>=pt[c].t_buf_h) return (pt[c].t_buf_t-pt[c].t_buf_h);
	else return (pt[c].t_buf_t+256-pt[c].t_buf_h);
}

void paoqiabyte(unsigned int c)
{
	if (pt[c].r_buf_t==pt[c].r_buf_h)return;
	if (0x00==pt[c].r_buf_t)pt[c].r_buf_t=255;
	else pt[c].r_buf_t--;
}
int set_mode(int com, int mode)
{
	if (0x00==isopened(com))return PORT_NOT_OPENED;
	if (com>3) return SUCCESS;
	pt[com].mode=mode;
	return SUCCESS;
}

void interrupt far irq9(__CPPARGS)
{
	struct time bt,it;
	int i,j;
	unsigned int port_rhr,port_lsr,port_thr;
	unsigned int flag=1;
	while(flag!=0)
	{
		flag=0;
		for (i=0;i<8;i++)
		{
			if (0x00!=_inportb(0x107+(i*8)))            
			{
				_outportb(0x100+(i*8)+_IER,0x00);
				continue;
			}
			port_lsr=0x100+(i*8)+_LSR;
			pt[i].r.LSR=_inportb(port_lsr);
			if(((pt[i].r.LSR&0x1e)!=0)||(((pt[i].r.LSR&0x01)!=0)&&((pt[i].r.IER&0x01)!=0))
			  ||(((pt[i].r.LSR&0x20)!=0)&&((pt[i].r.IER&0x02)!=0)))
			{
				flag|=intflag[i];
				port_rhr=0x100+(i*8)+_RHR;
				port_thr=0x100+(i*8)+_THR;
		
	  			while((pt[i].r.LSR&0x1e)!= 0)
				{
					_inportb(port_rhr);
					pt[i].r.LSR=_inportb(port_lsr);
				}
				while((pt[i].r.LSR&0x01)!= 0)
				{
					rece_led=1;
					pt[i].r_buf[pt[i].r_buf_t] = _inportb(port_rhr);
					pt[i].r_buf_t++;
					if (pt[i].r_buf_t==pt[i].r_buf_h)
					{
						pt[i].r_buf_h ++;
					}
					pt[i].r.LSR =_inportb(port_lsr);
				}
				if((pt[i].r.LSR&0x20)!= 0)
				{
					if (pt[i].t_buf_h==pt[i].t_buf_t)
	 				{
						pt[i].r.IER&=0xfd;
						_outportb(0x100+(i*8)+_IER,pt[i].r.IER);
						if (RS485==pt[i].mode)
						{
							gettime(&bt);
							while(!(_inportb(port_lsr)&0x40))
							{
								gettime(&it);
								j=it.ti_hund+100;
								j-=bt.ti_hund;
								j%=100;
								if (j>90)break;            //100ms超时
							}
							low_rts(i);
						}
						
					}
					else
					{
						send_led=0x01;
					        for (j=0;j<pt[i].fifo;j++)
						{
							_outportb(port_thr,pt[i].t_buf[pt[i].t_buf_h]);
							pt[i].t_buf_h++;
							if (pt[i].t_buf_h==pt[i].t_buf_t)
							{
								break;
							}
						}
					}
				}
			}
			else
			{
				flag&=~intflag[i];
			}
		}
	}
	_outportb(0x20,0x20);
	_outportb(0xa0,0x20);
}

void dint_e(unsigned int c)
{
	if (0x00==isopened(c))return;
	pt[c].r.IER&=0xfb;
	_outportb(0x100+(c*8)+_IER,pt[c].r.IER);
}
void eint_e(unsigned int c)
{
	if (0x00==isopened(c))return;
	pt[c].r.IER|=0x04;
	_outportb(0x100+(c*8)+_IER,pt[c].r.IER);
}
void dint_r(unsigned int c)
{
	if (0x00==isopened(c))return;
	pt[c].r.IER&=0xfe;
	_outportb(0x100+(c*8)+_IER,pt[c].r.IER);
}
void dint_t(unsigned int c)
{
	if (0x00==isopened(c))return;
	pt[c].r.IER&=0xfd;
	_outportb(0x100+(c*8)+_IER,pt[c].r.IER);
}
void eint_r(unsigned int c)
{
	if (0x00==isopened(c))return;
	pt[c].r.IER|=0x01;
	_outportb(0x100+(c*8)+_IER,pt[c].r.IER);
}
void eint_t(unsigned int c)
{
	if (0x00==isopened(c))return;
	pt[c].r.IER|=0x02;
	_outportb(0x100+(c*8)+_IER,pt[c].r.IER);
}

int receive_count(int com)
{
	if(pt[com].r_buf_t>=pt[com].r_buf_h) return (pt[com].r_buf_t-pt[com].r_buf_h);
	else return(pt[com].r_buf_t+256-pt[com].r_buf_h);
}

int getabyte(int com)
{
	int i;
	if (0x00==isopened(com)) return -1;
	if (0x00==receive_count(com))return -1;
	disable();
	i=pt[com].r_buf[pt[com].r_buf_h];
	pt[com].r_buf_h ++;
	enable();
	return i;
}
int putabyte(int com, unsigned char c)
{
	if (0x00==isopened(com)) return PORT_NOT_OPENED;
	pt[com].t_buf[pt[com].t_buf_t]=c;
	pt[com].t_buf_t ++;
	if (RS485==pt[com].mode)
	{
		high_rts(com);
	}
	eint_t(com);
	return SUCCESS;
}
int set_parity(int com, unsigned char parity)
{
	if (0x00==isopened(com)) return PORT_NOT_OPENED;
	pt[com].parity=parity;
	pt[com].r.LCR=_inportb(0x100+(com*8)+_LCR)&0xc7;
	pt[com].r.LCR |= ((pt[com].parity << 3) & 0x38);
	pt[com].r.LCR &= 0xff;
	_outportb(0x100+(com*8)+_LCR,pt[com].r.LCR);
	return SUCCESS;
}
int send_data(unsigned int c, unsigned char *source_buf, int l)
{
	int i;
	unsigned char d;
	if (0==isopened(c))return PORT_NOT_OPENED;
	if (0==l)
	{
		return SUCCESS;
	}
	for(i=0;i<l;i++)
	{
		pt[c].t_buf[pt[c].t_buf_t] = source_buf[i];
		pt[c].t_buf_t ++;
		if (pt[c].t_buf_t == pt[c].t_buf_h)
		{
			pt[c].t_buf_h ++;
		}
	}
	if (RS485==pt[c].mode)
	{
		high_rts(c);
	}
	eint_t(c);
	return SUCCESS;
}

void high_rts(unsigned int c)
{
	if (0==isopened(c))return;
	pt[c].r.MCR = 0x0a;
	_outportb(0x100+(c*8)+_MCR,pt[c].r.MCR);
}

void low_rts(unsigned int c)
{
	if (0==isopened(c))return;
	pt[c].r.MCR = 0x08;
	_outportb(0x100+(c*8)+_MCR,pt[c].r.MCR);
}

int openport(int com, unsigned int _baud, unsigned char _parity, unsigned char _databit, unsigned char _stop)
{
	int i,k;
	unsigned char fifo=B14;
	pt[com].ba = 0x100+(com*8);
	if (0xff==_inportb(pt[com].ba+7)) return PORT_ALREADY_OPEN;    
	_outportb(pt[com].ba+7,0xff);
	if (0xff!=_inportb(pt[com].ba+7)) return PORT_CANNOT_OPEN;    
	if (_databit > 0x03)pt[com].databit = D8;
	else pt[com].databit = _databit;
	if (_parity > 0x07)pt[com].parity = None;
	else pt[com].parity = _parity;
	if (_stop > 1)pt[com].stop = ST1;
	else pt[com].stop = _stop;
	pt[com].fifo = 14;
	pt[com].baud = _baud;
	pt[com].t_buf_h=0;
	pt[com].t_buf_t=0;
	pt[com].r_buf_h=0;
	pt[com].r_buf_t=0;
	pt[com].mode=RS232;
	switch (_baud)
	{
		case B300:
			pt[com].r.MSB = 0x01;
			pt[com].r.LSB = 0x80;
			break;
		case B600:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0xc0;
			break;
		case B900:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x80;
			break;
		case B1200:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x60;
			break;
		case B2400:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x30;
			break;
		case B4800:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x18;
			break;
		case B9600:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x0c;
			break;
		case B19200:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x06;
			break;
		case B38400:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x03;
			break;
		case B57600:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x02;
			break;
		case B115200:
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x01;
			break;
		default://B9600
			pt[com].r.MSB = 0x00;
			pt[com].r.LSB = 0x0c;
			break;
	}
	pt[com].r.FCR = 0x10;
	_outportb(pt[com].ba+_FCR,pt[com].r.FCR);
	pt[com].r.LCR = _inportb(pt[com].ba+_LCR) | 0x80;
	pt[com].r.LCR &= 0x84;
	pt[com].r.LCR |= pt[com].databit;
	pt[com].r.LCR |= ((pt[com].parity << 3) & 0x38);
	pt[com].r.LCR &= 0xfb;
	if (_stop)pt[com].r.LCR |= 0x04;
	_outportb(pt[com].ba+_LCR,pt[com].r.LCR);
	_outportb(pt[com].ba+_LSB,pt[com].r.LSB);
	_outportb(pt[com].ba+_MSB,pt[com].r.MSB);
	pt[com].r.LCR &= 0x7f;
	_outportb(pt[com].ba+_LCR,pt[com].r.LCR);
	pt[com].r.FCR = ((fifo<<6) & 0xc0) + 0x0f;
	_outportb(pt[com].ba+_FCR,pt[com].r.FCR);
	pt[com].fifo=((TL16C554==USE_COMMUNICATION_CHIP)?14:56);
	pt[com].r.MCR = (_inportb(pt[com].ba+_MCR) & 0xef) + 0x0a;
	_outportb(pt[com].ba+_MCR,pt[com].r.MCR);
	low_rts(com);
	k = 0;
	for (i=0;i<8;i++)
	{
		if (0x00==_inportb(0x100+(i*8)+7))
		{
			if (i==com)continue;
			k=1;
		}
	}
	if (0==k)
	{
		disable();
		irq_old = getvect(0x71);
		setvect (0x71,irq9);
		_outportb(0xa1,_inportb(0xa1)&0xf9);
		enable();
	}
	eint_r(com);
	eint_e(com);
	printf("%d,%d,%d,%d,%d,%d\n",com,_baud,_parity,k,_databit,_stop);
return PORT_SUCCESS_OPEN;
}

int isopened(unsigned int c)
{
	return (0x00==_inportb(0x100+(c*8)+7))?1:0;
}

int closeport(int com)
{
	int i;
	pt[com].ba=0x100+(com*8);
	if (0x00!=_inportb(pt[com].ba+7))return PORT_ALREADY_CLOSE;   
	_outportb(pt[com].ba+7,0x00);
	if (0xff!=_inportb(pt[com].ba+7))return PORT_CANNOT_CLOSE;    
	_outportb(pt[com].ba+_LCR,0x80);
	_outportb(pt[com].ba+_LSB,0x00);
	_outportb(pt[com].ba+_MSB,0x00);
	_outportb(pt[com].ba+_LCR,0x00);
	_outportb(pt[com].ba+_FCR,0x00);
	_outportb(pt[com].ba+_IER,0x00);
	for (i=0;i<8;i++)
	{
		if (0x00!=_inportb(0x100+(i*8)+7))return PORT_SUCCESS_CLOSE;
	}
	disable();
	setvect(0x71,irq_old);
	_outportb(0xa1,_inportb(0xa1)&0x02);
	_outportb(0x20,0x20);
	_outportb(0xa0,0xa0);
	enable();
	return PORT_SUCCESS_CLOSE;
}

void cardini(void)
{
	int i;
	for (i=0;i<8;i++)
	{
		_outportb(0x107+(i*8),0xff);
		pt[i].r.MSB=0x00;
		pt[i].r.LSB=0x00;
		pt[i].r.LSR=0x00;
		pt[i].r.IER=0x00;
		pt[i].r.LCR=0x00;
		pt[i].r.THR=0x00;
		pt[i].r.RHR=0x00;
		pt[i].r.MCR=0x00;
		pt[i].r.MSR=0x00;
		pt[i].r.IIR=0x00;
		pt[i].r.FCR=0x00;
		pt[i].r.STR=0x00;
		pt[i].fifo=14;
	   
	}
}

void far setbit9(int port)
{
	unsigned char c = _inportb(0x100+(port*8) + 3);
	c &= 0xc7;				
	c |= 0x28;				
	outportb(0x100+(port*8) + 3,c);
}

void far clearbit9(int port)
{
	unsigned char c = inportb(0x100+(port*8) + 3);
	c &= 0xc7;				
	c |= 0x38;				
	outportb(0x100+(port*8) + 3,c);
}


int putabyteEx(int com,unsigned char c)
{
	unsigned int i;
		if (RS485==pt[com].mode)
		{
			high_rts(com);
			for (i=0;i<30000;i++)
			{
				if (0x40==(_inportb(0x100+(com*8)+_LSR)&0x40))break;
			}
		}
		outportb (0x100+(com*8)+_THR,c);
		send_led^=0x01;
		if (RS485==pt[com].mode)
		{
			for (i=0;i<30000;i++)
			{
				if (0x40==(_inportb(0x100+(com*8)+_LSR)&0x40))break;
			}
			low_rts(com);
		}
	return SUCCESS;
}




⌨️ 快捷键说明

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