/* Serial.h */
void closeserial(void);
void interrupt com_int (void);
int getccb(void);
void closeserial(void);
void initserial (void);
void i_disable (void);
void i_enable (int pnum);
void resvects (void);
void setvects (void);
void comon (void);
int SerialOut (char x);
int setserial (int Port,int Speed,int Parity,int Bits,int StopBit);#define TRUE 1
#define FALSE 0
#define SBUFSIZ 0x2000#define COM1BASE 0x3F8 /* base port for com1 */
#define COM2BASE 0x2F8 /* base port for com2 *//* */
/* registers for serial port (not all used) */
/* */#define TX 0 /* Transmit register */
#define RX 0 /* receive register */
#define IER 1 /* Interrupt Enable */
#define IIR 2 /* Interrupt ID */
#define LCR 3 /* Line control */
#define MCR 4 /* Modem control */
#define LSR 5 /* Line Status */
#define MSR 6 /* Modem Status */
#define DLL 0 /* Divisor Latch Low */
#define DLH 1 /* Divisor latch high *//* */
/* Status values */
/* */#define RCVRDY 0x01 /* Data ready flag */
#define OVRERR 0x02 /* Overrun error */
#define PRTYERR 0x04 /* Parity error */
#define FRMERR 0x08 /* Framing error */
#define BRKINT 0x10 /* Break interrupt */
#define XMTRDY 0x20 /* Transmit register empty */
#define XMTRSR 0x40 /* Tx shift register empty *//* */
/* Status values for modem register */
/* */#define CTS 0x10
#define DSR 0x20
#define RI 0x40
#define CD 0x80#define DTR 0x01
#define RTS 0x02
#define OUT2 0x08#define IMR 0x21
#define ICR 0x20
#define EOI 0x20
#define RX 0
#define IIR 2
#define RX_MASK 7
#define RX_ID 4#define IRQ3 0xf7
#define IRQ4 0xef#define MCR 4
#define IER 1
#define MC_INT 8
#define RX_INT 1
#define RX_MASK 7
#define RX_ID 4#define BUFOVFL 1 /* buffer overflowed */#define COM1 1
#define COM2 2#define NO_PAR 0
#define EV_PAR 1
#define OD_PAR 2
---------------------------------------------------------------
/*
==========================
c.language/listings #115, from barryn, 8544 chars, Sat Aug 29 17:17:28 1987
--------------------------
TITLE: Communications routines in Turbo C The following code shows how to take advantage of some of
the TurboC extensions to the C language to do asynchronous
communications (without having to write supporting assembly-
language routines). The code was supplied by Peter Ibbotson of
Borland. After the communications-related functions themselves,
you'll find a small main() section of code that uses those functions
to implement a rudimentary glass-TTY terminal program. (I say
rudimentary to mean that control characters are not recognized and
there are no file transfer, dialing directory, etc. features.) First, here's Serial.C:
*//* SERIAL.C */#include "serial.h"
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#include <process.h>int SError;
int portbase=0;
void interrupt (*oldvects[2])();
char ccbuf[SBUFSIZ];
int startbuf=0;
int endbuf=0;/* this does the hard work (handling interrupts) */void interrupt com_int (void){ disable ();
if ((inportb (portbase+IIR) & RX_MASK)==RX_ID)
{ if (((endbuf+1) & 0x1fff)==startbuf)
SError=BUFOVFL;
ccbuf[endbuf++]=inportb (portbase+RX);
endbuf&=0x1fff;
};
outportb (ICR,EOI);
enable ();
}/* this routine returns the currently value in the buffer */int getccb(void){ int res;
if (endbuf==startbuf) return (-1);
res=(int) ccbuf[startbuf];
startbuf=(startbuf+1) % SBUFSIZ;
return (res);
}void setvects (void){ oldvects[0]=getvect(0x0b);
oldvects[1]=getvect(0x0c);
setvect(0x0b,com_int);
setvect(0x0c,com_int);
}void resvects (void){ setvect(0x0b,oldvects[0]);
setvect(0x0c,oldvects[1]);
}void i_enable (int pnum){ int c;
disable();
c = inportb (portbase+MCR) ¦ MC_INT;
outportb (portbase+MCR,c);
outportb (portbase+IER,RX_INT);
c = inportb (IMR) & (pnum==2 ? IRQ3 : IRQ4);
outportb (IMR,c);
enable();
}void i_disable (void){ int c;
disable ();
c=inportb (IMR) ¦ ~IRQ3 ¦ ~IRQ4;
outportb (IMR,c);
outportb (portbase + IER,0);
c=inportb (portbase+MCR) & ~MC_INT;
outportb (portbase+MCR,c);
enable ();
}void comon (void){ int c,pnum;
pnum = portbase == COM1BASE ? 1 : 2;
i_enable (pnum);
c=inportb (portbase + MCR) ¦ DTR ¦ RTS;
outportb (portbase + MCR,c);
}void initserial (void){ endbuf=startbuf=0;
setvects();
comon();
};void comoff (void){ i_disable ();
outportb (portbase+MCR,0);
}void closeserial(void){ comoff();
resvects();
};/* this outputs a serial character */int SerialOut (char x){ long timeout = 0x0000ffff;
outportb (portbase+MCR,OUT2¦DTR¦RTS);
/* wait for clear to send */
while ((inportb(portbase + MSR) & CTS)==0)
if ((--timeout)==0) return (-1);
timeout=0x0000ffff;
/* wait for outport register to clear */
while ((inportb(portbase+LSR) & DSR)==0)
if ((--timeout)==0) return (-1);
disable ();
outportb (portbase+TX,x);
enable ();
return (0);
}/* this routine sets which port we are working with */int SetPort (int Port){ int far * RS232_Addr;
int Offset; switch (Port) /* sort out the base address */
{ case 1 : Offset=0x0000; break; /* only ports one & two allowed */
case 2 : Offset=0x0002; break;
default : return (-1);
};
RS232_Addr=MK_FP(0x0040,Offset); /* find out where the port is */
if (*RS232_Addr==0) return (-1); /* if it ain't there return (-1)*/
portbase=*RS232_Addr; /* otherwise set portbase */
return (0);
}/* this routine sets the speed; will accept funny baud rates */int SetSpeed (int Speed){ char c;
int divisor;
if (Speed==0) return (-1); /* avoid divide by zero */
else divisor=(int)(115200L/Speed);
if (portbase==0) return (-11);
disable ();
c=inportb (portbase+LCR);
outportb (portbase+LCR,(c¦0x80)); /* set DLAB */
outportb (portbase+DLL,(divisor & 0x00ff)); /* set divisor */
outportb (portbase+DLH,((divisor>>8)&0x00ff));
outportb (portbase+LCR,c);
enable();
return (0);
}/* This routine set the LCR */int SetOthers (int Parity,int Bits,int StopBit){ int temp;
if (portbase==0) return (-1);
if ((Parity<NO_PAR) ¦¦ (Parity>OD_PAR)) return (-1);
if ((Bits<5) ¦¦ (Bits>8)) return (-1);
if ((StopBit<1) ¦¦ (StopBit>2)) return (-1);
temp=Bits-5;
temp¦=((StopBit==1) ? 0x00 : 0x04);
switch (Parity)
{ case NO_PAR : temp ¦= 0x00; break;
case OD_PAR : temp ¦= 0x08; break;
case EV_PAR : temp ¦= 0x18; break;
}
disable(); /* turn off interrupts */
outportb (portbase+LCR,temp);
enable(); /* turn em back on */
return (0);
}/* This routine sets the ports */int setserial (int Port,int Speed,int Parity,int Bits,int StopBit){ if (SetPort(Port)==-1) return(-1);
if (SetSpeed(Speed)==-1) return(-1);
if (SetOthers(Parity,Bits,StopBit)==-1) return (-1);
return (0);
}/* short demo */
/* this opens the ports and echos to screen until */
/* ESCape received */main (){ int c; if (setserial (COM1,2400,NO_PAR,8,1) ==-1) exit (1);
initserial();
printf("You're now in terminal mode. Press ESC to quit the program.\n\n");do {
if (kbhit()) {
c = getch();
if (c==27)
break;
SerialOut(c);
} if ((c=getccb())!=-1)
putchar (c); } while (c!=27); closeserial();
}
void closeserial(void);
void interrupt com_int (void);
int getccb(void);
void closeserial(void);
void initserial (void);
void i_disable (void);
void i_enable (int pnum);
void resvects (void);
void setvects (void);
void comon (void);
int SerialOut (char x);
int setserial (int Port,int Speed,int Parity,int Bits,int StopBit);#define TRUE 1
#define FALSE 0
#define SBUFSIZ 0x2000#define COM1BASE 0x3F8 /* base port for com1 */
#define COM2BASE 0x2F8 /* base port for com2 *//* */
/* registers for serial port (not all used) */
/* */#define TX 0 /* Transmit register */
#define RX 0 /* receive register */
#define IER 1 /* Interrupt Enable */
#define IIR 2 /* Interrupt ID */
#define LCR 3 /* Line control */
#define MCR 4 /* Modem control */
#define LSR 5 /* Line Status */
#define MSR 6 /* Modem Status */
#define DLL 0 /* Divisor Latch Low */
#define DLH 1 /* Divisor latch high *//* */
/* Status values */
/* */#define RCVRDY 0x01 /* Data ready flag */
#define OVRERR 0x02 /* Overrun error */
#define PRTYERR 0x04 /* Parity error */
#define FRMERR 0x08 /* Framing error */
#define BRKINT 0x10 /* Break interrupt */
#define XMTRDY 0x20 /* Transmit register empty */
#define XMTRSR 0x40 /* Tx shift register empty *//* */
/* Status values for modem register */
/* */#define CTS 0x10
#define DSR 0x20
#define RI 0x40
#define CD 0x80#define DTR 0x01
#define RTS 0x02
#define OUT2 0x08#define IMR 0x21
#define ICR 0x20
#define EOI 0x20
#define RX 0
#define IIR 2
#define RX_MASK 7
#define RX_ID 4#define IRQ3 0xf7
#define IRQ4 0xef#define MCR 4
#define IER 1
#define MC_INT 8
#define RX_INT 1
#define RX_MASK 7
#define RX_ID 4#define BUFOVFL 1 /* buffer overflowed */#define COM1 1
#define COM2 2#define NO_PAR 0
#define EV_PAR 1
#define OD_PAR 2
---------------------------------------------------------------
/*
==========================
c.language/listings #115, from barryn, 8544 chars, Sat Aug 29 17:17:28 1987
--------------------------
TITLE: Communications routines in Turbo C The following code shows how to take advantage of some of
the TurboC extensions to the C language to do asynchronous
communications (without having to write supporting assembly-
language routines). The code was supplied by Peter Ibbotson of
Borland. After the communications-related functions themselves,
you'll find a small main() section of code that uses those functions
to implement a rudimentary glass-TTY terminal program. (I say
rudimentary to mean that control characters are not recognized and
there are no file transfer, dialing directory, etc. features.) First, here's Serial.C:
*//* SERIAL.C */#include "serial.h"
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#include <process.h>int SError;
int portbase=0;
void interrupt (*oldvects[2])();
char ccbuf[SBUFSIZ];
int startbuf=0;
int endbuf=0;/* this does the hard work (handling interrupts) */void interrupt com_int (void){ disable ();
if ((inportb (portbase+IIR) & RX_MASK)==RX_ID)
{ if (((endbuf+1) & 0x1fff)==startbuf)
SError=BUFOVFL;
ccbuf[endbuf++]=inportb (portbase+RX);
endbuf&=0x1fff;
};
outportb (ICR,EOI);
enable ();
}/* this routine returns the currently value in the buffer */int getccb(void){ int res;
if (endbuf==startbuf) return (-1);
res=(int) ccbuf[startbuf];
startbuf=(startbuf+1) % SBUFSIZ;
return (res);
}void setvects (void){ oldvects[0]=getvect(0x0b);
oldvects[1]=getvect(0x0c);
setvect(0x0b,com_int);
setvect(0x0c,com_int);
}void resvects (void){ setvect(0x0b,oldvects[0]);
setvect(0x0c,oldvects[1]);
}void i_enable (int pnum){ int c;
disable();
c = inportb (portbase+MCR) ¦ MC_INT;
outportb (portbase+MCR,c);
outportb (portbase+IER,RX_INT);
c = inportb (IMR) & (pnum==2 ? IRQ3 : IRQ4);
outportb (IMR,c);
enable();
}void i_disable (void){ int c;
disable ();
c=inportb (IMR) ¦ ~IRQ3 ¦ ~IRQ4;
outportb (IMR,c);
outportb (portbase + IER,0);
c=inportb (portbase+MCR) & ~MC_INT;
outportb (portbase+MCR,c);
enable ();
}void comon (void){ int c,pnum;
pnum = portbase == COM1BASE ? 1 : 2;
i_enable (pnum);
c=inportb (portbase + MCR) ¦ DTR ¦ RTS;
outportb (portbase + MCR,c);
}void initserial (void){ endbuf=startbuf=0;
setvects();
comon();
};void comoff (void){ i_disable ();
outportb (portbase+MCR,0);
}void closeserial(void){ comoff();
resvects();
};/* this outputs a serial character */int SerialOut (char x){ long timeout = 0x0000ffff;
outportb (portbase+MCR,OUT2¦DTR¦RTS);
/* wait for clear to send */
while ((inportb(portbase + MSR) & CTS)==0)
if ((--timeout)==0) return (-1);
timeout=0x0000ffff;
/* wait for outport register to clear */
while ((inportb(portbase+LSR) & DSR)==0)
if ((--timeout)==0) return (-1);
disable ();
outportb (portbase+TX,x);
enable ();
return (0);
}/* this routine sets which port we are working with */int SetPort (int Port){ int far * RS232_Addr;
int Offset; switch (Port) /* sort out the base address */
{ case 1 : Offset=0x0000; break; /* only ports one & two allowed */
case 2 : Offset=0x0002; break;
default : return (-1);
};
RS232_Addr=MK_FP(0x0040,Offset); /* find out where the port is */
if (*RS232_Addr==0) return (-1); /* if it ain't there return (-1)*/
portbase=*RS232_Addr; /* otherwise set portbase */
return (0);
}/* this routine sets the speed; will accept funny baud rates */int SetSpeed (int Speed){ char c;
int divisor;
if (Speed==0) return (-1); /* avoid divide by zero */
else divisor=(int)(115200L/Speed);
if (portbase==0) return (-11);
disable ();
c=inportb (portbase+LCR);
outportb (portbase+LCR,(c¦0x80)); /* set DLAB */
outportb (portbase+DLL,(divisor & 0x00ff)); /* set divisor */
outportb (portbase+DLH,((divisor>>8)&0x00ff));
outportb (portbase+LCR,c);
enable();
return (0);
}/* This routine set the LCR */int SetOthers (int Parity,int Bits,int StopBit){ int temp;
if (portbase==0) return (-1);
if ((Parity<NO_PAR) ¦¦ (Parity>OD_PAR)) return (-1);
if ((Bits<5) ¦¦ (Bits>8)) return (-1);
if ((StopBit<1) ¦¦ (StopBit>2)) return (-1);
temp=Bits-5;
temp¦=((StopBit==1) ? 0x00 : 0x04);
switch (Parity)
{ case NO_PAR : temp ¦= 0x00; break;
case OD_PAR : temp ¦= 0x08; break;
case EV_PAR : temp ¦= 0x18; break;
}
disable(); /* turn off interrupts */
outportb (portbase+LCR,temp);
enable(); /* turn em back on */
return (0);
}/* This routine sets the ports */int setserial (int Port,int Speed,int Parity,int Bits,int StopBit){ if (SetPort(Port)==-1) return(-1);
if (SetSpeed(Speed)==-1) return(-1);
if (SetOthers(Parity,Bits,StopBit)==-1) return (-1);
return (0);
}/* short demo */
/* this opens the ports and echos to screen until */
/* ESCape received */main (){ int c; if (setserial (COM1,2400,NO_PAR,8,1) ==-1) exit (1);
initserial();
printf("You're now in terminal mode. Press ESC to quit the program.\n\n");do {
if (kbhit()) {
c = getch();
if (c==27)
break;
SerialOut(c);
} if ((c=getccb())!=-1)
putchar (c); } while (c!=27); closeserial();
}
But I want to use this program under WINNT/2000 system.I think 'outport' functions can't work correctly.
Think you for your help.
Windows下用
CreateFile("\\\\..\\COM1",...)
不行吗?
在本站的程序员大本营中有很多这样的源码和例子,你可以去找找。
Now I want a Network program.
http://www.csdn.net/dev/Delphi/
中VCL控件大集合中找"通讯"一栏中的前几个便是。
Command to machine link with a serial port and/or network,and other PCs
link with network.I also want to finf a man to help.Thinks .
Good luck.