⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs232.c

📁 串口通讯工具
💻 C
字号:
/*///////////////////////////////////////////////////////////
//COMRXTX.CPP  for asyn serial communication (RX/TX)
//edited by Xiong Guangming and Gong Jianwei 
//Turbo C++3.0
////////////////////////////////////////////////////////////*/
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#include <stdlib.h>

#define BUFFLEN 1024
#define BASELEN 3
#define LINES   5  
 


short bExit_Flag=0;
/*/COM1产生的硬件中断号为IQR4,对应的中断向量为为0CH
//打开COM1*/
void OpenPort()
{
	InitCOM();  /*/初始化串口*/

	/*/读入由参数给定的中断向量值,并将它作为中断函数的远地址*/
	asyncoldvect=getvect(cominterrupt);
	disable();       /*/关中断  (在安装中断以前,最好用disable ( )函数关闭中断)*/
	inportb(combase);
	inportb(combase+6);
	inportb(combase+3);
	inportb(combase+2);
	outportb(combase+4,0x08);
	outportb(combase+1,0x01);
	if(comirq>7)
	{
		outportb(0x21,inportb(0X21)&0xfb);/*//打开主片IRQ2*/
		outportb(0xA1,inportb(0XA1)&(0xfe<<(comirq-8)));/*/打开从片IRQ*/
	}
	else
		outportb(0x21,inportb(0X21)&(0xfe<<comirq));/*/打开主片IRQ*/
	
	setvect(cominterrupt,asyncint);
	enable();       /*/*开中断*/
}

int irq_setup(unsigned base)
{
        /*/ Returns -1 if not found -- otherwise returns interrupt level*/

        char ier, mcr, imrm, imrs, maskm, masks, irqm, irqs;

        disable();          /*/ disable all CPU interrupts*/
        ier = inportb(base+1);   /*/ read IER*/
        outportb(base+1,0);      /*/* disable all UART ints*/
        while (!(inportb(base+5)&0x20));  // wait for the THR to be empty
        mcr = inportb(base+4);   /*/ read MCR*/
        outportb(base+4,0x0F);   /*/ connect UART to irq line*/
        imrm = inportb(0x21);    /*/ read contents of master ICU mask register*/
        imrs = inportb(0xA1);    /*/ read contents of slave ICU mask register*/
       
        enable();
        if (irqs&0x80)       /*/ slave interrupt occured*/
          return (irqs&0x07)+8;
        if (irqm&0x80)       /*/ master interrupt occured*/
          return irqm&0x07;
        return -1;
};

/*/中断服务程序,从COM1接收数据
//注意在TC2.0下,下面函数的...要去掉*/
void interrupt far asyncint(...)
{
	//unsigned char ch;
	Buffer[buffin++] = inportb(combase);/*/ 读字符到缓冲区*/
	if (buffin >= BUFFLEN)  /*/ 缓冲区满*/
		buffin=0;           /*/ 指针复位*/
	outportb(0x20,0x20);
	outportb(0xA0,0x20);
}

void ClosePort(void) /*/关闭中断*/
{
	disable();
	outportb(combase+1,0x00);
	outportb(combase+4,0x00);
	if(comirq>7)
	{
		outportb(0x21,inportb(0X21)|~(0xfb));/*/关闭主片IRQ*/
		outportb(0xA1,inportb(0XA1)|~(0xfe<<(comirq-8)));/*/关闭从片IRQ*/
	}
	else
		outportb(0X21,inportb(0X21)&~(0xfe<<comirq));/*/关闭主片IRQ*/
	enable();
	setvect(cominterrupt,asyncoldvect);
}

void InitCOM()/*/ 对COM1串口初始化,设置串口参数*/
{

	outportb(combase+3,0x80);  /*/将设置波特率*/
	/* 设置波特率,低位在前、高位在后;(部分波特率器参数如下)
     波特率    分频器H   分频器L
	 ...
	 4800       00        18H
	 7200       00        10H
	 9600       00        0CH
	 ....	 
  */
	outportb(combase,0x0C);   /*/波特率为9600bps*/
	outportb(combase+1,0x00);

	/*设置停止位、奇偶校验位、等
	D7:为1表示设置波特率;为0,其他;
	D6:为1,是,强迫在数据线上输出逻辑0;为0,则否;
	D5:1,校验位可变;0,不变;
	D4D3:×0,无校验位;01,奇校验位;11,偶校验位;
	D2:0,1个停止位;1,1.5个停止位;
	D1D0:00,5位数据位;01,6位数据位;10,7位数据位;11,8位数据位;
	*/
	outportb(combase+3,0x03);   /*/8个数据位,1个停止位、无奇偶校验*/

	outportb(combase+4,0x08|0x0b);
	outportb(combase+1,0x01);
}


unsigned char read_char(void)
{
	unsigned unch;
	if(buffout != buffin)
	{
		unch = Buffer[buffout];
		buffout++;
		if(buffout >= BUFFLEN)
			buffout=0;
		return(unch);
	}
	else
		return(0xff);
}


/* send char 发送字符函数 */
void send_char(unsigned char unch)
{
   while ( ((inp( combase + 5)) & 0x40 ) == 0); /*/和0x40相与 可取出D6位进行判断*/
   outportb(combase , unch);
}

int uart_detect(unsigned base)
{
        /*/ Returns 0 if no UART detected

       // int olddata=inportb(base+4);*/
        outportb(base+4, 0x10);
        if ((inportb(base+6) & 0xf0)) return 0;
        return 1;
};

int base_check(char *base)
{
int len=0,n;
char c;
/*/检查长度*/
	while(*(base+len)!='\0')
		len++;
	if (len>BASELEN)
	{
			fprintf(stdout,	"\nThe length of port address shouldn't be larger than %d.",BASELEN);
			return 0;
	}
	/*/检查合法性*/
	for (n=0;n<len;n++)
	{
		c=*(base+n);
		if (((c>=48 && c<=57)||(c>=65 && c<=70)||(c>=97 && c<=102))!=1)
		{
			fprintf(stdout,	"\nInvalid port address.");
			return 0;
		}
	}	
	return 1;
}

void TestSerial()
{
	int unChar,rChar=0xff,c=0;
	int sx,sy,rx,ry,zx,zy;
		/*/测试端口*/
    fprintf(stdout,	"\n");
    /*/界面*/
	fprintf(stdout,	"\n\nData send:\n");
	XPOS_START=wherex();
	YPOS_START=wherey();
	fprintf(stdout,"\n\n\n\n\n\nData received:"	);
	rx=XPOS_START;
	ry=YPOS_START+LINES+2;
	zx=XPOS_START;
	zy=YPOS_START+LINES+10;
	gotoxy(XPOS_START,YPOS_START);

    unChar=0x21;
		while (1)
		{
			  /*/打印发送字符*/
			  gotoxy(sx,sy);
				fprintf(stdout,"%c",unChar);
				sx=wherex();
				sy=wherey();
			
     		send_char(unChar); 
     		delay(50);
     				
     		/*/打印接收字符*/
     		rChar = read_char();  
     		gotoxy(rx,ry);
     		if (rChar!=0xff)
     				fprintf(stdout,"%c",rChar);
     		else
     			{
						fprintf(stdout,"COM is not connected.");
     				printf( "\a" );
     				break;
     			}
				rx=wherex();
				ry=wherey();  
				/*/打印提示信息*/
				gotoxy(zx,zy);
				if (unChar==rChar)
					fprintf(stdout,"Succeed!");	
				else
					{
						fprintf(stdout,"Error!");
						printf( "\a" );
					}	
				/*/超过范围回到原始坐标点*/	
					if (sy>=YPOS_START+LINES)
  		{
					sx=XPOS_START;
					rx=XPOS_START;
	  				for(sy=YPOS_START;sy<=YPOS_START+LINES;sy++)
					{	
					gotoxy(sx,sy);
					clreol();
					}
					for(ry=YPOS_START+LINES+2;ry<=YPOS_START+2*LINES+1;ry++)
					{	
					gotoxy(rx,ry);
					clreol();
					}
					sy=YPOS_START;
					ry=YPOS_START+LINES+2;
			}
     		unChar++;
     		if (unChar>0x7e)
     				unChar=0x21;
	
				/*/键盘处理   */			
  			if (kbhit())
  					c=getch();
  			if (c==0x1B	)
          {	
          	bExit_Flag = 1;  
          	break;
	  			}
  			if (c==0x09	)
  				break;
  	}
  	
		ClosePort(); /*/关闭串口*/	
	
}
/*/以下为主函数*/
main(int argc, char *argv[] )

{
	unsigned char unChar;
	short bExit_Flag=0;
	int sx,sy,rx,ry,i;
	int a,checkirq;
	struct text_info winstatus;
  	 gettextinfo(&winstatus);

  /*/初始化端口*/
		/*while (irq>15 || irq<3)
		{	fprintf(stdout,	"\nInput error.Please input a number between 3 and 15:");			
	  	fflush(stdin);
	  	scanf("%d",&irq);
	  }*/
	  if (argc!=3)
	  {
	  	fprintf(stdout,	"\nTest command format is :"
                        "\nfilename serialport_address serialport_intvector "
						"\nExample: rs232 3f8 4 "
						"\nCOM1 : 3F8 4 "
                        "\nCOM2 : 2F8 3 "
                        "\nCOM3 : 3E8 7 "
                        "\nCOM4 : 2E8 5 ");	
			return -1;
	  }
		if(base_check(argv[1])==0)
			return -1;
	  combase=strtol(argv[1],NULL,16);
	  comirq=strtol(argv[2],NULL,10);
		if(comirq>15 || comirq<3)
		{
			fprintf(stdout,	"\nIRQ must be a number between 3 and 15:");		
			return -1;
		}
		/*checkirq=irq_setup(combase);
		if (comirq!=checkirq)
		{
			fprintf(stdout,	"\nInput error!IRQ is %d.",checkirq);
			return -1;
		}*/
		clrscr();
		
	  	switch(comirq)
	  	{
	  		case 3: cominterrupt=0x0b;
	  						break;
	  		case 4: cominterrupt=0x0c;
	  						break;
	  		case 5: cominterrupt=0x0d;
	  						break;
	  		case 6: cominterrupt=0x0e;
	  						break;
	  		case 7: cominterrupt=0x0f;
	  						break;
	  		case 8: cominterrupt=0x70;
	  						break;
	  		case 9: cominterrupt=0x71;
	  						break;
	  		case 10: cominterrupt=0x72;
	  						break;
	  		case 11: cominterrupt=0x73;
	  						break;
	  		case 12: cominterrupt=0x74;
	  						break;
	  		case 13: cominterrupt=0x75;
	  						break;
	  		case 14: cominterrupt=0x76;
	  						break;
	  		case 15: cominterrupt=0x77;
	  						break;
	  	}
	  
  	OpenPort();
  	//开始测试
  	fprintf(stdout,	"\nAddress %x , IRQ%d testing.Press [ESC] to quit.\n",combase,comirq);		
	fprintf(stdout, "\n\nReady to Receive DATA\n"
			"press [ESC] to quit...\n\n");
	fprintf(stdout, "\nPress keyboard to transmit data to PC"
	 				"\nReceive data from PC\n\n"
					"\nSTART_TEST:\n");


	do {
		if (kbhit())
		{
			unChar=getch();
			/* Look for an ESC key */
			switch (unChar)
			{
			case 0x1B:   /*/ESC的ASCII值为27*/
				bExit_Flag = 1;  /* Exit program */
				break;
			/*/You may want to handle other keys here*/
			}
			if(!bExit_Flag)
				send_char(unChar); /*/发送键入的字符*/
		}
		unChar = read_char();  /*/从缓冲区中读数*/
		delay(100);
		if (unChar != 0xff)
		{
			fprintf(stdout,"%2x ",unChar);
		}
	} while (!bExit_Flag);

	ClosePort(); /*/关闭串口*/
	
return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -