📄 rs232.c
字号:
#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 + -