📄 serial.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 + -