请教关于TC下的串口编程,先谢了!

cqwty 2005-12-13 03:46:32
偶使用的是TC2.0,编译通过,但是链接时候_dos_getvect,_dos_setvect这两个设置中断的函数出错,请问这是什么原因啊,懂的大哥指教一下啊!

源代码是网上下的,如下
#include <dos.h>
#include <bios.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <graphics.h>
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
#define SER_RBF 0
#define SER_THR 0
#define SER_IER 1
#define SER_IIR 2
#define SER_LCR 3
#define SER_MCR 4
#define SER_LSR 5
#define SER_MSR 6
#define SER_DLL 0
#define SER_DLH 1
#define SER_BAUD_1200 96
#define SER_BAUD_2400 48
#define SER_BAUD_9600 12
#define SER_BAUD_19200 6
#define SER_GP02 8
#define COM_1 0x3F8
#define COM_2 0x2F8 /*/ base port address of port 1*/
#define SER_STOP_1 0 /*/ 1 stop bit per character*/
#define SER_STOP_2 4 /*/ 2 stop bits per character*/
#define SER_BITS_5 0 /*/ send 5 bit characters*/
#define SER_BITS_6 1 /*/ send 6 bit characters*/
#define SER_BITS_7 2 /*/ send 7 bit characters*/
#define SER_BITS_8 3 /*/ send 8 bit characters*/
#define SER_PARITY_NONE 0 /*/ no parity*/
#define SER_PARITY_ODD 8 /*/ odd parity*/
#define SER_PARITY_EVEN 24 /*/ even parity*/
#define SER_DIV_LATCH_ON 128 /*/ used to turn reg 0,1 into divisor latch*/
#define PIC_IMR 0x21 /*/ pic's interrupt mask reg.*/
#define PIC_ICR 0x20 /*/ pic's interupt control reg.*/
#define INT_SER_PORT_0 0x0C /*/ port 0 interrupt com 1 & 3*/
#define INT_SER_PORT_1 0x0B /*/ port 0 interrupt com 2 & 4*/
#define SERIAL_BUFF_SIZE 128 /*/ current size of circulating receive buffer*/
void interrupt far (*Old_Isr)(__CPPARGS); /*/ holds old com port interrupt handler*/
char ser_buffer[SERIAL_BUFF_SIZE]; /*/ the receive buffer*/
int ser_end = -1,ser_start=-1; /*/ indexes into receive buffer*/
int ser_ch, char_ready=0; /*/ current character and ready flag*/
int old_int_mask; /*/ the old interrupt mask on the PIC*/
int open_port; /*/ the currently open port*/
int serial_lock = 0; /*/ serial ISR semaphore so the buffer*/
/*/ isn't altered will it is being written*/
/*/ to by the ISR*/

/*-------------写串口-----------------*/
void interrupt far Serial_Isr(__CPPARGS)
{
serial_lock = 1;
ser_ch = inp(open_port + SER_RBF);
if (++ser_end > SERIAL_BUFF_SIZE-1)
ser_end = 0;
ser_buffer[ser_end] = ser_ch;
++char_ready;
outp(PIC_ICR,0x20);
serial_lock = 0;
}

int Ready_Serial()
{
return(char_ready);
}
/*--------------读串口--------------*/
int Serial_Read()
{
int ch;
while(serial_lock){}
if (ser_end != ser_start)
{
if (++ser_start > SERIAL_BUFF_SIZE-1)
ser_start = 0;
ch = ser_buffer[ser_start];
if (char_ready > 0)
--char_ready;
return(ch);
}
else
return(0);
}
/*--------------写串口-----------------*/
Serial_Write(char ch)
{
while(!(inp(open_port + SER_LSR) & 0x20)){}
asm cli
outp(open_port + SER_THR, ch);
asm sti
}
/*-----------初始化串口---------------*/
Open_Serial(int port_base, int baud, int configuration)
{
open_port = port_base;
outp(port_base + SER_LCR, SER_DIV_LATCH_ON);
outp(port_base + SER_DLL, baud);
outp(port_base + SER_DLH, 0);
outp(port_base + SER_LCR, configuration);
outp(port_base + SER_MCR, SER_GP02);
outp(port_base + SER_IER, 1);
if (port_base == COM_1)
{
Old_Isr = _dos_getvect(INT_SER_PORT_0);
_dos_setvect(INT_SER_PORT_0, Serial_Isr);
printf("\nOpening Communications Channel Com Port #1...\n");
}
else
{
Old_Isr = _dos_getvect(INT_SER_PORT_1);
_dos_setvect(INT_SER_PORT_1, Serial_Isr);
printf("\nOpening Communications Channel Com Port #2...\n");
}
old_int_mask = inp(PIC_IMR);
outp(PIC_IMR, (port_base==COM_1) ? (old_int_mask & 0xEF) : (old_int_mask & 0xF7 ));
}
/*-------------关闭串口--------------*/
Close_Serial(int port_base)
{
outp(port_base + SER_MCR, 0);
outp(port_base + SER_IER, 0);
outp(PIC_IMR, old_int_mask );
if (port_base == COM_1)
{
_dos_setvect(INT_SER_PORT_0, Old_Isr);
printf("\nClosing Communications Channel Com Port #1.\n");
}
else
{
_dos_setvect(INT_SER_PORT_1, Old_Isr);
printf("\nClosing Communications Channel Com Port #2.\n");
}
}
/*-------------发送应用----------------*/
void main(int argc,char *argv[])
{
char ch,press;
int done=0;
FILE *fp;
argc=2;
argv[1]="test.cpp";
if(argc<2)
{
printf("\nUsage:display filename.wav!!!");
exit(0);
}
if((fp=fopen(argv[1],"r+b"))==NULL)
{
printf("cannot open the file\n");
exit(0);
}
fseek(fp, 0, SEEK_SET);
Open_Serial(COM_1,SER_BAUD_9600,SER_PARITY_NONE | SER_BITS_8 | SER_STOP_1);
printf("press any key to begin sending");
getch();
Serial_Write(' ');
while(!done&&ch != EOF)
{
ch = fgetc(fp);
if(ch==EOF) Serial_Write(27);
Serial_Write(ch);
if (kbhit())
{
press=getch();
if (press==27)
{
Serial_Write(27);
done=1;
}
}
}
Close_Serial(COM_1);
fclose(fp);
}
...全文
232 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
leoman2005 2005-12-15
  • 打赏
  • 举报
回复
这位兄台用过
WINIO_API bool _stdcall GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);
WINIO_API bool _stdcall SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);
没有?
屋顶上的老猫 2005-12-15
  • 打赏
  • 举报
回复
我刚才也遇到了这个问题,不同机器配置delay()也不一样,看样子和主频是有很大关系的!研究研究!
leoman2005 2005-12-15
  • 打赏
  • 举报
回复
turbo c2.0里面的delay(1000000000000)才一秒啊,我刚刚调的,delay和机器有关吧!
那键盘发送是这样吗?
屋顶上的老猫 2005-12-15
  • 打赏
  • 举报
回复
C语言里sleep()是秒级函数,sleep(0.02)是错误的,用delay(20)!

能不能行,要自己试!^_^
leoman2005 2005-12-15
  • 打赏
  • 举报
回复
高手们大家好,我最近负责ps2口设备的通讯,写了个(i8042)键盘发送数据的代码。如下(c语言):
outportb(0x64,0X0d1);
outportb(0X60,'A');sleep(0.02);
outportb(0X60,'A');sleep(0.02);
outportb(0X60,'A');sleep(0.02);
outportb(0X60,'A');sleep(0.02);
outportb(0X60,'A');
需求是向ps2口没隔20毫秒发送一个‘a’,请问高手这样能行吗?
屋顶上的老猫 2005-12-14
  • 打赏
  • 举报
回复
<DOS+TC>虽然历史悠久,可在某些领域是有很大空间的!谓之尺有所短,寸有所长!
fiftymetre 2005-12-13
  • 打赏
  • 举报
回复
还有人在用TC啊唉我还真不会用呢呵呵UP一下吧
屋顶上的老猫 2005-12-13
  • 打赏
  • 举报
回复
串口通信一般采用环形队列的方法,根据相应协议可以写一组函数:

void Init(void); //初始化
void check(unsigned char states); //校验

void enableports(void); //开放端口
void disableports(void); //关闭端口

void interrupt far asyncint(void); //中断服务程序

void putb(unsigned char ch); //发送
unsigned char getb(void); //接受
屋顶上的老猫 2005-12-13
  • 打赏
  • 举报
回复
这个程序没有校验啊!遇到干扰要出错的,呵呵!
屋顶上的老猫 2005-12-13
  • 打赏
  • 举报
回复
又是串口编程啊!最近搞这个东西很流行吗?^_^

程序太乱太多,没太看!这部分程序在什么系统运行的_dos_getvect,_dos_setvect应该没有定义吧!这两个中断设置函数,应该是在开放、闭合端口时应用的!DOS下用getvect()和setvect()!

cqwty 2005-12-13
  • 打赏
  • 举报
回复
自己搞定了
_dos_getvect,_dos_setvect
dos下使用应改为getvect setvect

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧