- 论坛徽章:
- 0
|
写了一个串口通信的小程序,在TC下调了很久,没有调通,请教CU。源代码及注释如下:
/*程序在两台主机上同时运行,程序一运行即显示“show me a word: ”, */
/*——此后两台主机均查询串口上是否收到对方传送的响应信号 */
/*——("send")——通过键盘输入,则另一台主机开始发送文件,"receive"——接收 */
/*——“bash”(文件名);为了简单一点,此为一个固定文件。文件大小小于1KB。 */
#define TRR 0x3f8 /*定义符号TRR为接收缓冲器/发送保持续冲器的口地址*/
#define IER 0x3f9 /*定义符号IER为中断允许寄存器的口地址*/
#define IIR 0x3fa /*定义符号IIR为中断识别寄存器的口地址*/
#define LCR 0x3fb /*定义符号LCR为线路控制寄存器的口地址*/
#define MCR 0x3fc /*定义符号MCR为modem控制寄存器的口地址*/
#define LSR 0x3fd /*定义符号LSR为线路寄存器的口地址*/
#define MSR 0x3fe /*定义符号MSR为modem状态寄存器的口地址*/
#define COMPORT 0 /*定义符号COMPORT为通讯口号 COM1:0,COM2:1*/
#define COMINTN 0x0c /*定义符号COMINTN为中断类型号 COM1:0x0c,COM2:0x0b*/
#define OPENCOM 0xef /*定义符号OPENCOM为开放通信中断所需的屏蔽字 COM1:0xef,COM2:0xf7*/
#include <dos.h>
#include <stdio.h>
#include <bios.h>
#include <string.h>
#include <stdlib.h>
char rxd[1024]; /*定义rxd为接收缓冲区,长度为1KB*/
char txd[1024]; /*定义txd为发送缓冲区,长度为1KB*/
char *pr=rxd; /*用指针pr来访问接收缓冲寄存器*/
char *pt=txd; /*用指针pt来访问发送缓冲寄存器*/
FILE *sfile,*rfile;
int len=900; /*文件大小固定,设为900字节*/
int rflag; /*定义用于主程序与中断程序之间进行联络的变量*/
int error_cnt=0; /*定义记录通信出错次数的变量*/
void interrupt comint() /*通信中断服务程序*/
{
char status;
int i;
static int no=0;
enable(); /*开中断*/
status=inportb(LSR); /*读线路状态寄存器*/
switch(inportb(IIR)&0x07) /*读中断状态寄存器,并测试*/
{
case 4: /*接收中断,接收数据准备好*/
if (status&0x0e) {error_cnt++;break;} /*“与”的结果不等于0,说明至少出现了三种情况之一:*/
/*——帧错,重叠,奇偶校验错*/
*pr=inportb(TRR); /*将接收到的字符写到接收缓冲区*/
pr++;
break;
case 2: /*发送中断,发送保持寄存器空*/
if(no<len) /*未发送完,继续发送*/
{outportb(TRR,*(pt+no));no++;} /*将需发送的字符从发送缓冲区写到发送保持寄存器*/
else
{
for(i=1;i<10000;i++); /*最后一个字符送入发送保持缓冲器后再次进入中断时的处理。*/
/*——此循环是为了延时,等待最后一个字符真正发送完。*/
outportb(IER,inportb(IER)&0xfd); /*禁止发送中断*/
outportb(MCR,inportb(MCR)&0xfd); /*复位RTS*/
no=0;
}
break;
case 0:inportb(MSR);break; /*Modem状态改变引起的中断,通过读该寄存器来清除MSR的低4位*/
case 6:inportb(LSR);break; /*接收错误引起的中断,通过读该寄存器来清除LSR的低5位*/
}
outportb(0x20,0x20); /*发中断结束命令*/
}
int main()
{
int i,j;
unsigned char mask;
char cu[20];
rflag=0;
mask=inportb(0x21); /*取系统原中断屏蔽字*/
bioscom(0,0xee,COMPORT); /*初始化COM1:9.6kb/s,奇校验,2位停止位,7位数据位*/
disable(); /*关中断*/
setvect(COMINTN,comint); /*设置中断向量。comint是中断函数名,也是中断服务程序入口地址*/
outportb(MCR,inportb(MCR)|0x09);/*置位OUT2和DTR*/
outportb(IER,0x05); /*允许接受中断和接受出错中断*/
outportb(0x21,mask & OPENCOM); /*取消对通信口中断的屏蔽*/
error_cnt=0;
printf("show me a word: n" ;
scanf("%s",cu);
enable(); /*开中断*/
if(*cu=='s'){
rflag=1; /*表明本机为发送文件的主机,准备发送文件*/
sfile=fopen("bash","rb" ;
fread(pt,100,9,sfile); /*将要发送的文件读入发送缓冲区*/
outportb(IER,inportb(IER)|0x02); /*允许发送中断*/
outportb(MCR,inportb(MCR)|0x02); /*置位RTS,即请求发送*/
}
if(*cu=='r'){
rfile=fopen("bash","wb" ; /*新建文件bash*/
for(j=0;j<30000;j++); /*经过一定的延时*/
fwrite(pr,100,9,rfile); /*将要接受的文件读入接受缓冲区*/
}
for(; {
for(i=0;i<20000;i++)
{
if(bioskey(1)) /*按任意键,在恢复系统原中断屏蔽字后,程序结束*/
{
printf("n通信出错次数为%dn",error_cnt);
outportb(0x21,mask);
exit(0);
}
}
}
getch();
} |
|