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

📄 rs232.c

📁 LINUX的简单应用
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include "rs232.h"

#define RBR              0    /* Receive buffer register */
#define THR              0    /* Transmit holding reg.   */
#define IER              1    /* Interrupt Enable reg.   */
#define IER_RX_DATA      1    /* Enable RX interrupt bit */
#define IER_THRE         2    /* Enable TX interrupt bit */
#define IIR              2    /* Interrupt ID register   */
#define IIR_MODEM_STATUS 0    /* Modem stat. interrupt ID*/
#define IIR_TRANSMIT     2    /* Transmit interrupt ID   */
#define IIR_RECEIVE      4    /* Receive interrupt ID    */
#define IIR_LINE_STATUS  6    /* Line stat. interrupt ID */
#define LCR              3    /* Line control register   */
#define LCR_DLAB         0x80 /* Divisor access bit      */
#define LCR_EVEN_PARITY  0x8  /* Set parity 'E' bits     */
#define LCR_ODD_PARITY   0x18 /* Set parity 'O' bits     */
#define LCR_NO_PARITY    0    /* Set parity 'N' bits     */
#define LCR_1_STOP_BIT   0    /* Bits to set 1 stop bit  */
#define LCR_2_STOP_BITS  4    /* Bits to set 2 stop bits */
#define LCR_5_DATA_BITS  0    /* Bits to set 5 data bits */
#define LCR_6_DATA_BITS  1    /* Bits to set 6 data bits */
#define LCR_7_DATA_BITS  2    /* Bits to set 7 data bits */
#define LCR_8_DATA_BITS  3    /* Bits to set 8 data bits */
#define MCR              4    /* Modem control register  */
#define MCR_DTR          1    /* Bit to turn on DTR      */
#define MCR_RTS          2    /* Bit to turn on RTS      */
#define MCR_OUT1         4    /* Bit to turn on OUT1     */
#define MCR_OUT2         8    /* Bit to turn on OUT2     */
#define LSR              5    /* Line Status register    */
#define MSR              6    /* Modem Status register   */
#define DLL              0    /* Divisor latch LSB       */
#define DLM              1    /* Divisor latch MSB       */

#define IntEoiReg			0xFF22		//End-of-Interrupt Register
#define IntMaskReg			0xFF28		//Interrupt Mask Register

#define Int3CtrlReg			0xFF3E		//IRQ7 for external Comm1/2/3/4
#define Int3NumIntr			0x000F		//external Comm1/2/3/4 Interrupt Number
#define Int3NumEoi			0x000F		//external Comm1/2/3/4 EOI

#define Com1UartBase		0x50
#define Com2UartBase		0x58
#define Com3UartBase		0x60
#define Com4UartBase		0x68
/*#define Com1RcvHldReg		0x50
#define Com1TrnHldReg		0x50
#define Com1IntEnbReg		0x51
#define Com1IntStusReg		0x52
#define Com1FIFOCtrlReg		0x52
#define Com1ModeCtrlReg		0x54
#define Com1LineStusReg		0x55

#define Com2RcvHldReg		0x58
#define Com2TrnHldReg		0x58
#define Com2IntEnbReg		0x59
#define Com2IntStusReg		0x5a
#define Com2FIFOCtrlReg		0x5a
#define Com2ModeCtrlReg		0x5c
#define Com2LineStusReg		0x5d

#define Com3RcvHldReg		0x60
#define Com3TrnHldReg		0x60
#define Com3IntEnbReg		0x61
#define Com3IntStusReg		0x62
#define Com3FIFOCtrlReg		0x62
#define Com3ModeCtrlReg		0x64
#define Com3LineStusReg		0x65

#define Com4RcvHldReg		0x68
#define Com4TrnHldReg		0x68
#define Com4IntEnbReg		0x69
#define Com4IntStusReg		0x6a
#define Com4FIFOCtrlReg		0x6a
#define Com4ModeCtrlReg		0x6c
#define Com4LineStusReg		0x6d
  */

extern unsigned int timer;
extern int GetPass(unsigned int early,unsigned int late);
//extern unsigned int Com1_Timer;
//extern unsigned char Com1_State;
extern unsigned int G93RcvTimer;
extern void Show_Io(int id,int tms);

void interrupt (far * old_vector)(__CPPARGS)=NULL;

PORT *com1=NULL;
PORT *com2=NULL;
PORT *com3=NULL;
PORT *com4=NULL;

/*void check_485delay(int cmd)
{
	static unsigned int com3dltimer=0,com4dltimer=0;
	static unsigned int com3stimer=0,com4stimer=0;
	static unsigned char comdlstate=0;
	switch(cmd)
	{
	case 0:
		if(comdlstate&0x01)
		{
			if(GetPass(com3dltimer,timer)>=2)
			{
				comdlstate&=0xfe;
				outportb( com3->uart_base + LCR,0x3b);//LCR_NO_PARITY | LCR_8_DATA_BITS);
				outportb( com3->uart_base + MCR,MCR_RTS | MCR_DTR | MCR_OUT2);//0x0b
			}
		}
		if(comdlstate&0x02)
		{
			if(GetPass(com4dltimer,timer)>=2)
			{
				comdlstate&=0xfd;
				outportb( com4->uart_base + MCR,MCR_RTS | MCR_DTR | MCR_OUT2);//0x0b
			}
		}
		if(comdlstate&0x04)
		{
			if(GetPass(com3stimer,timer)>=2)
			{
				comdlstate&=0xfb;
				outportb( com3->uart_base+IER,IER_THRE);
			}
		}
		if(comdlstate&0x08)
		{
			if(GetPass(com4stimer,timer)>=2)
			{
				comdlstate&=0xf7;
				outportb( com4->uart_base+IER,IER_THRE);
			}
		}
		break;
	case 1:
		com3dltimer=timer;
		comdlstate|=1;
		break;
	case 2:
		com4dltimer=timer;
		comdlstate|=2;
		break;
	case 3:
		com3stimer=timer;
		comdlstate|=4;
		break;
	case 4:
		com4stimer=timer;
		comdlstate|=8;
		break;
	default:
		break;
	}
}*/

void interrupt far com_int(__CPPARGS)
{   //由于4个串口使用同一个中断号,即同一个中断入口地址,因此在此中断服务程序中要用4个分支来判断是
	//哪一个串口产生的中断,可利用4个串口各自的中断标志寄存器来判别
	unsigned char aa,bb,cc,dd;
	unsigned char c;
	int i;

	aa=inportb(Com1UartBase+IIR)&0x0f;
	bb=inportb(Com2UartBase+IIR)&0x0f;
	cc=inportb(Com3UartBase+IIR)&0x0f;
	dd=inportb(Com4UartBase+IIR)&0x0f;
	while(aa!=0x01 || bb!=0x01 || cc!=0x01 || dd!=0x01)
	{
		switch(aa)   //由于FIFO可使用,中断标志寄存器的前两位就是用来表示FIFO是否可用,所以&0x0f
		{
		case 0x02:    //发送中断
			if ( com1->out.read_index == com1->out.write_index )
				outportb( Com1UartBase + IER, IER_RX_DATA );
			else
			{
				c = com1->out.buffer[ com1->out.read_index++ ];
				outportb( Com1UartBase + THR, c );
			}
			break;
		//case 0x04:   //接收中断
		//case 0x0c:   //接收超时中断,04和0c用来判断接收中断
		//	while(inportb(Com1UartBase+LSR)&0x01)
		//	{
		//		c = (unsigned char) inportb( Com1UartBase+RBR );
		//		if (((unsigned char)(com1->in.write_index+1 )) != com1->in.read_index)
		//		{
		//			com1->in.buffer[ com1->in.write_index++ ] =  c ;
		//		}
		//	}
		//	break;
		default:
			//Show_Io(6,20);
			while(inportb(Com1UartBase+LSR)&0x01)
			{
				c = (unsigned char) inportb( Com1UartBase+RBR );
				if (((unsigned char)(com1->in.write_index+1 )) != com1->in.read_index)
				{
					com1->in.buffer[ com1->in.write_index++ ] =  c ;
					//outportb( Com2UartBase + THR, c );//debug

				}
			}
			//outportb(0x89,aa);
			inportb(Com1UartBase+RBR);
			break;
        }
		switch(bb)  //com2的中断标志寄存器
		{
		case 0x02:    //发送中断
			if ( com2->out.read_index == com2->out.write_index )
				outportb( Com2UartBase + IER, IER_RX_DATA );
			else
			{
				c = com2->out.buffer[ com2->out.read_index++ ];
				outportb( Com2UartBase + THR, c );
			}
			break;
		case 0x04:   //接收中断
		case 0x0c:   //接收超时中断,04和0c用来判断接收中断
			c = (unsigned char) inportb( Com2UartBase+RBR );
			if (((unsigned char)(com2->in.write_index+1 )) != com2->in.read_index)
			{
				com2->in.buffer[ com2->in.write_index++ ] =  c ;
			}
			break;
		default:
			inportb(Com2UartBase+RBR);
			break;
        }
		switch(cc)  //com3的中断标志寄存器
		{
		case 0x02:    //发送中断
			if ( com3->out.read_index == com3->out.write_index )
			{
				outportb( Com3UartBase + IER, IER_RX_DATA );
				for(i=0;i<500;i++);
				outportb(Com3UartBase + LCR,0x3b);//LCR_NO_PARITY | LCR_8_DATA_BITS);
				outportb(Com3UartBase + MCR,MCR_RTS | MCR_DTR | MCR_OUT2);//0x0b
				
			}
			else
			{
				if(0==com3->out.read_index)
					outportb( com3->uart_base + LCR, LCR_ODD_PARITY | LCR_8_DATA_BITS | 0x20);//奇校验
				else
					outportb( com3->uart_base + LCR,LCR_EVEN_PARITY | LCR_8_DATA_BITS | 0x20);//偶校验
				c = com3->out.buffer[ com3->out.read_index++ ];
				outportb( Com3UartBase + THR, c );
			}
			break;
		default:
		//case 0x04:   //接收中断
		//case 0x0c:   //接收超时中断,04和0c用来判断接收中断
			while(1)
			{
				i=inportb(Com3UartBase+LSR);
				if(0==(i&0x01))
					break;
				c = (unsigned char) inportb( Com3UartBase+RBR );
				if(i&0x04)//校验错
				{
					//printf("par error");
					com3->in.write_index=0;
					if(0x8b==c)
						com3->in.buffer[ com3->in.write_index++ ] =  c ;
				}
				else if(com3->in.write_index>0)
				{
					com3->in.buffer[ com3->in.write_index++ ] =  c ;
					if(com3->in.write_index==17)
						G93RcvTimer=timer;
				}
			}
			break;
		//default:
		//	inportb(Com3UartBase+RBR);

⌨️ 快捷键说明

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