/*------------------------------------------------------------------*
SERIAL.CPP
The following code shows how to take advantage of some of
the Turbo C++ extensions to the C++ language to do asynchronous
communications without having to write supporting assembly-
language routines.
This program bypasses the less-than-adequate PC BIOS
communications routines and installs a serial interrupt
handler. Direct access to PC hardware allows the program to
run at faster baud rates and eliminates the need for
the main program to continuously poll the serial port for
data; thus implementing background communications. Data that
enters the serial port is stored in a circular buffer.
* Compile this program with Test Stack Overflow OFF.
*------------------------------------------------------------------*/
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include "serial.h"
#include "..\wba\gw\CusType.h"
#include "..\UnGetch\UnGetch.h"
#define VERSION 0x0101
#define FALSE 0
#define TRUE 1
#define NOERROR 0 /* No error */
#define BUFOVFL 1 /* Buffer overflowed */
#define ESC 0x1B /* ASCII Escape character */
#define ASCII 0x007F /* Mask ASCII characters */
#define SBUFSIZ 0x0010 /* Serial buffer size */
int SError = NOERROR;
int portbase = 0;
void interrupt(*oldvects[2])(...);
static char ccbuf[SBUFSIZ];
unsigned int startbuf = 0;
unsigned int endbuf = 0;
UINT KeyCode = 0;
/* Handle communications interrupts and put them in ccbuf */
void interrupt com_int(...)
{
disable();
/*
if ((inportb(portbase + IIR) & RX_MASK) == RX_ID)
{
if (((endbuf + 1) & SBUFSIZ - 1) == startbuf)
SError = BUFOVFL;
ccbuf[endbuf++] = inportb(portbase + RXR);
endbuf &= SBUFSIZ - 1;
}
*/
/* Put the serial code into keyboard buffer */
KeyCode = inportb(portbase + RXR);
if(KeyCode != 0x0a) //ignores the linefeed character '\n'
{
if(KeyCode == 0x0d) KeyCode = 0x1c0d;
UnGetch(KeyCode);
}
/* Signal end of hardware interrupt */
outportb(ICR, EOI);
enable();
}
/* Output a character to the serial port */
serial& serial::operator<<( char x )
{
long int timeout = 0x0000FFFFL;
outportb(portbase + MCR, MC_INT | DTR | RTS);
/* Wait for Clear To Send from modem */
while ((inportb(portbase + MSR) & CTS) == 0)
if (!(--timeout))
return *this;
timeout = 0x0000FFFFL;
/* Wait for transmitter to clear */
while ((inportb(portbase + LSR) & XMTRDY) == 0)
if (!(--timeout))
return *this;
disable();
outportb(portbase + TXR, x);
enable();
return *this;
}
/* Output a string to the serial port */
serial& serial::operator<<( char *string )
{
while (*string)
{
(*this) << *string;
string++;
}
return *this;
}
/* This routine returns the current value in the buffer */
serial &serial::operator>>( char &ch )
{
if (endbuf == startbuf)
{
ch = -1;
return *this;
}
ch = ccbuf[startbuf];
startbuf++;
startbuf %= SBUFSIZ;
return *this;
}
/* Install our functions to handle communications */
void setvects(void)
{
oldvects[0] = getvect(0x0B);
oldvects[1] = getvect(0x0C);
setvect(0x0B, com_int);
setvect(0x0C, com_int);
}
/* Uninstall our vectors before exiting the program */
void resvects(void)
{
setvect(0x0B, oldvects[0]);
setvect(0x0C, oldvects[1]);
}
/* Turn on communications interrupts */
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 == COM1 ? IRQ4 : IRQ3);
outportb(IMR, c);
enable();
}
/* Turn off communications interrupts */
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();
}
/* Tell modem that we're ready to go */
void comm_on(void)
{
int c, pnum;
pnum = (portbase == COM1BASE ? COM1 : COM2);
i_enable(pnum);
c = inportb(portbase + MCR) | DTR | RTS;
outportb(portbase + MCR, c);
}
/* Go off-line */
void serial::comm_off(void)
{
i_disable();
outportb(portbase + MCR, 0);
}
void serial::init_serial(void)
{
endbuf = startbuf = 0;
setvects();
comm_on();
}
serial::~serial()
{
comm_off();
resvects();
}
/* Set the port number to use */
int serial::SetPort(int Port)
{
int Offset, far *RS232_Addr;
switch (Port)
{ /* Sort out the base address */
case COM1 : Offset = 0x0000;
break;
case COM2 : Offset = 0x0002;
break;
default : return (-1);
}
RS232_Addr = (int far *)MK_FP(0x0040, Offset); /* Find out where the port is. */
if (*RS232_Addr == NULL) return (-1);/* If NULL then port not used. */
portbase = *RS232_Addr; /* Otherwise set portbase */
return (0);
}
/* This routine sets the speed; will accept funny baud rates. */
/* Setting the speed requires that the DLAB be set on. */
int serial::SetSpeed(int Speed)
{
char c;
int divisor;
if (Speed == 0) /* Avoid divide by zero */
return (-1);
else
divisor = (int) (115200L/Speed);
if (portbase == 0)
return (-1);
disable();
c = inportb(portbase + LCR);
outportb(portbase + LCR, (c | 0x80)); /* Set DLAB */
outportb(portbase + DLL, (divisor & 0x00FF));
outportb(portbase + DLH, ((divisor >> 8) & 0x00FF));
outportb(portbase + LCR, c); /* Reset DLAB */
enable();
return (0);
}
/* Set other communications parameters */
int serial::SetOthers(int Parity, int Bits, int StopBit)
{
int setting;
if (portbase == 0) return (-1);
if (Bits < 5 || Bits > 8) return (-1);
if (StopBit != 1 && StopBit != 2) return (-1);
if (Parity != NO_PARITY && Parity != ODD_PARITY && Parity != EVEN_PARITY)
return (-1);
setting = Bits-5;
setting |= ((StopBit == 1) ? 0x00 : 0x04);
setting |= Parity;
disable();
outportb(portbase + LCR, setting);
enable();
return (0);
}
/* Set up the port */
serial::serial(int Port, int Speed, int Parity, int Bits, int StopBit)
{
flag = 0;
if (SetPort(Port))
flag = -1;
if (SetSpeed(Speed))
flag = -1;
if (SetOthers(Parity, Bits, StopBit))
flag = -1;
if (!flag)
init_serial();
}
/* Control-Break interrupt handler */
int c_break(void)
{
i_disable();
fprintf(stderr, "\nStill online.\n");
return(0);
}
没有合适的资源?快使用搜索试试~ 我知道了~
DOS系统下的串口键盘编程驱动
共13个文件
obj:3个
cpp:2个
asm:2个
4星 · 超过85%的资源 需积分: 9 18 下载量 90 浏览量
2009-09-06
22:54:30
上传
评论
收藏 32KB RAR 举报
温馨提示
在工厂领域,有些老的条码扫描器是串口接口的,本代码实现了从串口读取条码器的数据并加到BIOS的键盘缓冲区,给人的感觉就像是从键盘键入的,以保证现有从键盘读数据的应用程序不需改动地使用串口扫描器。
资源推荐
资源详情
资源评论
收起资源包目录
COM_KEY.rar (13个子文件)
COM_KEY
COM_KEY.DSK 3KB
COM_KEY.EXE 18KB
COM_KEY.PRJ 5KB
SERIAL.H 6KB
MAIN.BAK 1007B
UNGETCH.OBJ 1KB
SERIAL.OBJ 7KB
MAIN.OBJ 2KB
MAIN.CPP 1KB
SERIAL.CPP 7KB
SERIAL.ASM 34KB
SERIAL.BAK 7KB
MAIN.ASM 4KB
共 13 条
- 1
资源评论
- zhouyuan_20022013-03-31代码不错,正是我想要的,参考一下自己做个window工具,呵呵
- alixweng2013-09-07程序写的很棒,C++的代码,很好的学习案例!
LovelyPenguin
- 粉丝: 16
- 资源: 38
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功