本次系统(PC104系统)共计需要6路串口,其中:
(1)、主板BIOS上有2路RS232串口。
(2)、PCM3614板卡上有4路RS485串口。
一、串口通信基地址
(1)、主板BIOS内COM1口基地址选择=0x03F8 , IRQ选择 = 4
(2)、主板BIOS内COM2口基地址选择=0x02F8 , IRQ选择 = 3
(3)、PCM3614板卡内COM1口基地址设置=0x0300 , IRQ跳线设置 = 5
(4)、PCM3614板卡内COM2口基地址设置=0x0308 , IRQ跳线设置 = 6
(5)、PCM3614板卡内COM3口基地址设置=0x0310 , IRQ跳线设置 = 7
(6)、PCM3614板卡内COM4口基地址设置=0x0318 , IRQ跳线设置 = 9
二、PCM3614板卡上的JP3,JP4,JP6,JP7功能是选择PCM3614板卡内 COM1、COM2、COM3、COM4口的IRQ中断请求号。
研华PCM3614规定:通过JP3,JP4,JP6,JP7选择中断请求号只能选择3,4,5,6,7,9,10,11,12,15.,而且研华的规定和IBM的规定一致。
JP3跳线专门用来设置PCM3614板卡内的COM1口IRQ中断请求号
JP4跳线专门用来设置PCM3614板卡内的COM2口IRQ中断请求号
JP6跳线专门用来设置PCM3614板卡内的COM3口IRQ中断请求号
JP7跳线专门用来设置PCM3614板卡内的COM4口IRQ中断请求号
短接JP3,JP4,JP6,JP7拨码开关的跳线设置IRQ中断号,短接从左到右依次为 15,12,11,10,9,7,6,5,4,3
三、SW1拨码开关的M0位用来选择PCM3614板卡上COM1、COM2、COM3、COM4的基地址
(2.1) 当M0位拨到ON
PCM3614板卡上的COM1、COM2、COM3、COM4的基地址和标准基地址相同,即:
PCM3614板卡上COM1口基地址COM1=0x03F8
PCM3614板卡上COM2口基地址COM2=0x02F8
PCM3614板卡上COM3口基地址COM3=0x03E8
PCM3614板卡上COM4口基地址COM4=0x02E8
(2.2) 当M0位拨到OFF
PCM3614板卡上COM1、COM2、COM3、COM4的基地址则由拨码开关SW1.1-SW1.7决定。
而且每个基地址之间固定相差8.
例如:SW1.0-SW1.7 按照如下方式拨:
SW1.1 = ON
SW1.2 = ON
SW1.3 = ON
SW1.4 = ON
SW1.5 = ON
SW1.6 = OFF
SW1.7 = OFF
则 PCM3614板卡上COM1口基地址 = 0x0300
PCM3614板卡上COM2口基地址 = 0x0308
PCM3614板卡上COM3口基地址 = 0x0310
PCM3614板卡上COM4口基地址 = 0x0318
本工程必须采用M0位拨到OFF,即:每个基地址之间固定相差8。
四、SW1拨码开关的M1位用来选择PCM3614板卡上COM1、COM2、COM3、COM4的中断号是采用独立方式还是共享方式
所谓独立方式即:PCM3614板卡上4个COM口分别分配1个IRQ中断号.
(3.1)当M1拨到ON
选择共享方式
(3.2)当M1拨到OFF
选择独立方式
五、源程序.h
typedef unsigned char BOOL;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned int INT16U;
typedef signed int INT16S;
typedef unsigned long INT32U;
typedef signed long INT32S;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
//MODBUS
#define MSCOMM_BUFFER_LENGTH 255
//
// 8250寄存器
//-------------------------------------------------------------------------------------------
//说明:当线路控制寄存器(LCR)的bit7=0 : DLAB=0,允许访问接收/发送及中断允许寄存器
// 当线路控制寄存器(LCR)的bit7=1 : DLAB=1,允许访问波特率因子寄存器
//-------------------------------------------------------------------------------------------
// 寄存器缩写 基地址 读/写 注释 DLAB
//
#define TXR /*(0x03F8)*/ 0 // Write 发送保持寄存器 (DLAB=0)
#define RXR 0 // Read 接收数据寄存器 (DLAB=0)
#define IER /*(0x03F9)*/ 1 // Read/Write 中断允许寄存器 (DLAB=x)
#define DLL 0 // Read/Write 波特率低八位 (DLAB=1)
#define DLH 1 // Read/Write 波特率高八位 (DLAB=1)
#define IIR /*(0x03FA)*/ 2 // Read 中断标识寄存器 (DLAB=x)
#define FCR 2 // Write FIFO控制寄存器 (DLAB=x)
#define LCR /*(0x03FB)*/ 3 // Read/Write 线路控制寄存器 (DLAB=x)
#define MCR /*(0x03FC)*/ 4 // Read/Write MODEM控制寄存器 (DLAB=x)
#define LSR /*(0x03FD)*/ 5 // Read 线路状态寄存器 (DLAB=x)
#define MSR /*(0x03FE)*/ 6 // Read MODEM状态寄存器 (DLAB=x)
//8250
#define IER_RX_INT 0x01
#define IER_TX_INT 0x02
#define MCR_DTR 0x01
#define MCR_RTS 0x02
#define MCR_INT 0x08
#define IIR_TX_ID 0x02
#define IIR_RX_ID 0x04
#define IIR_MASK 0x07
//BAUD
#define BAUD_1200 0
#define BAUD_2400 1
#define BAUD_4800 2
#define BAUD_9600 3
#define BAUD_14400 4
#define BAUD_19200 5
#define BAUD_38400 6
#define BAUD_57600 7
#define BAUD_115200 8
//STOP
#define STOP_1 0
#define STOP_2 1
//UPM
#define NONE_PARITY 0 // 无校验 0x00
#define ODD_PARITY 1 // 奇校验 0x08
#define EVEN_PARITY 2 // 偶校验 0x18
//PCM-3614 JP3----> IRQ 3,4,5,6,7,9,10,11,12,15
//IRQ0 -- interrupt No=0x08 ----> Time (no used)
//IRQ1 -- interrupt No=0x09 ----> Keyboard (no used)
//IRQ2 -- interrupt No=0x0A ----> Redirect IRQ9 (no used)
//IRQ3 -- interrupt No=0x0B ----> COM2 (ok)
//IRQ4 -- interrupt No=0x0C ----> COM1 (ok)
//IRQ5 -- interrupt No=0x0D ----> LPT2 (ok)
//IRQ6 -- interrupt No=0x0E ----> FDD (ok)
//IRQ7 -- interrupt No=0x0F ----> LPT1 (ok)
//IRQ8 -- interrupt No=0x70 ----> CMOS (no used)
//IRQ9 -- interrupt No=0x71 ----> Redirect IRQ2 (ok)
//IRQ10-- interrupt No=0x72 ----> Reversed (ok)
//IRQ11-- interrupt No=0x73 ----> Reversed (ok)
//IRQ12-- interrupt No=0x74 ----> Mouse (ok)
//IRQ13-- interrupt No=0x75 ----> FPU (no used)
//IRQ14-- interrupt No=0x76 ----> Primary IDE (no used)
//IRQ15-- interrupt No=0x77 ----> Secondary ide (ok)
//IRQ --- > MASK
//IRQ0 ----- MASK = 0xFE ----> 1111 1110 ----> Time (no used)
//IRQ1 ----- MASK = 0xFD ----> 1111 1101 ----> Keyboard (no used)
//IRQ2 ----- MASK = 0xFB ----> 1111 1011 ----> Redirect IRQ9 (no used)
//IRQ3 ----- MASK = 0xF7 ----> 1111 0111 ----> COM2 (ok)
//IRQ4 ----- MASK = 0xEF ----> 1110 1111 ----> COM1 (ok)
//IRQ5 ----- MASK = 0xDF ----> 1101 1111 ----> LPT2 (ok)
//IRQ6 ----- MASK = 0xBF ----> 1011 1111 ----> FDD (ok)
//IRQ7 ----- MASK = 0x7F ----> 0111 1111 ----> LPT1 (ok)
//IRQ8 ----- MASK = 0xFE ----> 1111 1110 ----> CMOS (no used)
//IRQ9 ----- MASK = 0xFD ----> 1111 1101 ----> Redirect IRQ2 (ok)
//IRQ10----- MASK = 0xFB ----> 1111 1011 ----> Reversed (ok)
//IRQ11----- MASK = 0xF7 ----> 1111 0111 ----> Reversed (ok)
//IRQ12----- MASK = 0xEF ----> 1110 1111 ----> Mouse (ok)
//IRQ13----- MASK = 0xDF ----> 1101 1111 ----> FPU (no used)
//IRQ14----- MASK = 0xBF ----> 1011 1111 ----> Primary IDE (no used)
//IRQ15----- MASK = 0x7F ----> 0111 1111 ----> Secondary ide (ok)
//8259-IRQ MASK
#define IRQ0_MASK 0xFE
#define IRQ1_MASK 0xFD
#define IRQ2_MASK 0xFB
#define IRQ3_MASK 0xF7
#define IRQ4_MASK 0xEF
#define IRQ5_MASK 0xDF
#define IRQ6_MASK 0xBF
#define IRQ7_MASK 0x7F
#define IRQ8_MASK 0xFE
#define IRQ9_MASK 0xFD
#define IRQ10_MASK 0xFB
#define IRQ11_MASK 0xF7
#define IRQ12_MASK 0xEF
#define IRQ13_MASK 0xDF
#define IRQ14_MASK 0xBF
#define IRQ15_MASK 0x7F
//8259-IRQ Interrupt No
#define IRQ0 0x08
#define IRQ1 0x09
#define IRQ2 0x0A
#define IRQ3 0x0B
#define IRQ4 0x0C
#define IRQ5 0x0D
#define IRQ6 0x0E
#define IRQ7 0x0F
#define IRQ8 0x70
#define IRQ9 0x71
#define IRQ10 0x72
#define IRQ11 0x73
#define IRQ12 0x74
#define IRQ13 0x75
#define IRQ14 0x76
#define IRQ15 0x77
//8259
#define COM1_BASE 0x03F8 // BIOS-COM1
#define COM1_IRQ IRQ4
#define COM1_IRQ_MASK IRQ4_MASK
#define COM2_BASE 0x02F8 // BIOS-COM2
#define COM2_IRQ IRQ3
#define COM2_IRQ_MASK IRQ3_MASK
#define COM3_BASE 0x0300 // PCM-3614-COM1
#define COM3_IRQ IRQ5
#define COM3_IRQ_MASK IRQ5_MASK
#define COM4_BASE 0x0308 // PCM-3614-COM2
#define COM4_IRQ IRQ6
#define COM4_IRQ_MASK IRQ6_MASK
#define COM5_BASE 0x0310 // PCM-3614-COM3
#define COM5_IRQ IRQ7
#define COM5_IRQ_MASK IRQ7_MASK
#define COM6_BASE 0x0318 // PCM-3614-COM4
#define COM6_IRQ IRQ9
#define COM6_IRQ_MASK IRQ9_MASK
#define INTC_MASK 0x21 // Interrupt Mask Register port
#define INTC_EOI 0x20 // Interrupt Control Port
#define IRQ_EOI 0x20 // End of Interrupt
//COM
#define COM1 1
#define COM2 2
#define COM3 3
#define COM4 4
#define COM5 5
#define COM6 6
//ESC KEY
#define ESC_KEY 0x011B
六、源程序.c
#include <stdio.h>
#include <dos.h>
/
// set USART interrupt vect
/
void SetSerial_Vect(unsigned int COM)
{
switch (COM)
{
case COM1: // 0x03F8 ---> BIOS-COM1
com1_old_vect = getvect(COM1_IRQ);
setvect(COM1_IRQ, com1_vect);
break;
case COM2: // 0x02F8 ---> BIOS-COM2
com2_old_vect = getvect(COM2_IRQ);
setvect(COM2_IRQ, com2_vect);
break;
case COM3: // 0x0300 ---> PCM3614-COM1
com3_old_vect = getvect(COM3_IRQ);
setvect(COM3_IRQ, com3_vect);
break;
case COM4: // 0x0308 ---> PCM3614-COM2
com4_old_vect = getvect(COM4_IRQ);
setvect(COM4_IRQ, com4_vect);
break;
case COM5: // 0x0310 ---> PCM3614-COM3
com5_old_vect = getvect(COM5_IRQ);
setvect(COM5_IRQ, com5_vect);
break;
case COM6: // 0x0318 ---> PCM3614-COM4
com6_old_vect = getvect(COM6_IRQ);
setvect(COM6_IRQ, com6_vect);
break;
}
}
/
// restore USART interrupt vect
/
void RestoreSerial_Vect(unsigned int COM)
{
switch (COM)
{
case COM1: // 0x03F8 ---> BIOS-COM1
setvect(COM1_IRQ, com1_old_vect);
break;
case COM2: // 0x02F8 ---> BIOS-COM2
setvect(COM2_IRQ, com2_old_vect);
break;
case COM3: // 0x0300 ---> PCM3614-COM1
setvect(COM3_IRQ, com3_old_vect);
break;
case COM4: // 0x0308 ---> PCM3614-COM2
setvect(COM4_IRQ, com4_old_vect);
break;
case COM5: // 0x0310 ---> PCM3614-COM3
setvect(COM5_IRQ, com5_old_vect);
break;
case COM6: // 0x0318 ---> PCM3614-COM4
setvect(COM6_IRQ, com6_old_vect);
break;
}
}
/
// open USART
/
void OpenSerial(unsigned int COM,unsigned char irq,unsigned char BAUD,unsigned char STOP,unsigned char UPM)
{
MSCOM_Init(COM , BAUD , STOP , UPM);
switch (COM)
{
case COM1: // 0x03F8 ---> BIOS-COM1
outportb((unsigned int)COM1_BASE + MCR , MCR_INT);
outportb((unsigned int)COM1_BASE + IER , IER_RX_INT);
if (irq >= 8)
{
outportb(0x21,inportb(0x21) & IRQ2_MASK); // open IRQ2
outportb(0xA1,inportb(0xA1) & COM1_IRQ_MASK); // open IRQX
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) & COM1_IRQ_MASK);
}
break;
case COM2: // 0x02F8 ---> BIOS-COM2
outportb((unsigned int)COM2_BASE + MCR , MCR_INT);
outportb((unsigned int)COM2_BASE + IER , IER_RX_INT);
if (irq >= 8)
{
outportb(0x21,inportb(0x21) & IRQ2_MASK); // open IRQ2
outportb(0xA1,inportb(0xA1) & COM2_IRQ_MASK); // open IRQX
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) & COM2_IRQ_MASK);
}
break;
case COM3: // 0x0300 ---> PCM3614-COM1
outportb((unsigned int)COM3_BASE + MCR , MCR_INT);
outportb((unsigned int)COM3_BASE + IER , IER_RX_INT);
if (irq >= 8)
{
outportb(0x21,inportb(0x21) & IRQ2_MASK); // open IRQ2
outportb(0xA1,inportb(0xA1) & COM3_IRQ_MASK); // open IRQX
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) & COM3_IRQ_MASK);
}
break;
case COM4: // 0x0308 ---> PCM3614-COM2
outportb((unsigned int)COM4_BASE + MCR , MCR_INT);
outportb((unsigned int)COM4_BASE + IER , IER_RX_INT);
if (irq >= 8)
{
outportb(0x21,inportb(0x21) & IRQ2_MASK); // open IRQ2
outportb(0xA1,inportb(0xA1) & COM4_IRQ_MASK); // open IRQX
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) & COM4_IRQ_MASK);
}
break;
case COM5: // 0x0310 ---> PCM3614-COM3
outportb((unsigned int)COM5_BASE + MCR , MCR_INT);
outportb((unsigned int)COM5_BASE + IER , IER_RX_INT);
if (irq >= 8)
{
outportb(0x21,inportb(0x21) & IRQ2_MASK); // open IRQ2
outportb(0xA1,inportb(0xA1) & COM5_IRQ_MASK); // open IRQX
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) & COM5_IRQ_MASK);
}
break;
case COM6: // 0x0318 ---> PCM3614-COM4
outportb((unsigned int)COM6_BASE + MCR , MCR_INT);
outportb((unsigned int)COM6_BASE + IER , IER_RX_INT);
if (irq >= 8)
{
outportb(0x21,inportb(0x21) & IRQ2_MASK); // open IRQ2
outportb(0xA1,inportb(0xA1) & COM6_IRQ_MASK); // open IRQX
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) & COM6_IRQ_MASK);
}
break;
}
}
/
// close USART
/
void CloseSerial(unsigned int COM,unsigned char irq)
{
switch (COM)
{
case COM1: // 0x03F8 ---> BIOS-COM1
if (irq >= 8)
{
outportb(0x21,inportb(0x21) | ~IRQ2_MASK); // close IRQ2
outportb(0xA1,inportb(0xA1) | ~COM1_IRQ_MASK); // close IRQx
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) | ~COM1_IRQ_MASK);
}
outportb((unsigned int)COM1_BASE + IER , 0);
outportb((unsigned int)COM1_BASE + MCR , 0);
break;
case COM2: // 0x02F8 ---> BIOS-COM2
if (irq >= 8)
{
outportb(0x21,inportb(0x21) | ~IRQ2_MASK); // close IRQ2
outportb(0xA1,inportb(0xA1) | ~COM2_IRQ_MASK); // close IRQx
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) | ~COM2_IRQ_MASK);
}
outportb((unsigned int)COM2_BASE + IER , 0);
outportb((unsigned int)COM2_BASE + MCR , 0);
break;
case COM3: // 0x0300 ---> PCM3614-COM1
if (irq >= 8)
{
outportb(0x21,inportb(0x21) | ~IRQ2_MASK); // close IRQ2
outportb(0xA1,inportb(0xA1) | ~COM3_IRQ_MASK); // close IRQx
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) | ~COM3_IRQ_MASK);
}
outportb((unsigned int)COM3_BASE + IER , 0);
outportb((unsigned int)COM3_BASE + MCR , 0);
break;
case COM4: // 0x0308 ---> PCM3614-COM2
if (irq >= 8)
{
outportb(0x21,inportb(0x21) | ~IRQ2_MASK); // close IRQ2
outportb(0xA1,inportb(0xA1) | ~COM4_IRQ_MASK); // close IRQ10
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) | ~COM4_IRQ_MASK);
}
outportb((unsigned int)COM4_BASE + IER , 0);
outportb((unsigned int)COM4_BASE + MCR , 0);
break;
case COM5: // 0x0310 ---> PCM3614-COM3
if (irq >= 8)
{
outportb(0x21,inportb(0x21) | ~IRQ2_MASK); // close IRQ2
outportb(0xA1,inportb(0xA1) | ~COM5_IRQ_MASK); // close IRQ10
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) | ~COM5_IRQ_MASK);
}
outportb((unsigned int)COM5_BASE + IER , 0);
outportb((unsigned int)COM5_BASE + MCR , 0);
break;
case COM6: // 0x0318 ---> PCM3614-COM4
if (irq >= 8)
{
outportb(0x21,inportb(0x21) | ~IRQ2_MASK); // close IRQ2
outportb(0xA1,inportb(0xA1) | ~COM6_IRQ_MASK); // close IRQ10
}
else
{
outportb(INTC_MASK,inportb(INTC_MASK) | ~COM6_IRQ_MASK);
}
outportb((unsigned int)COM6_BASE + IER , 0);
outportb((unsigned int)COM6_BASE + MCR , 0);
break;
}
}
//
//初始化8250
//------------------------------------------------
//(1).对波特率进行设置时,须先将除数锁存器访问位DLAB置1,
// 然后按照低在前高在后的顺序将除数因子写入寄存器.
//(2).对数据位进行设置时,须先将除数锁存器访问位DLAB置0.
//------------------------------------------------
// D7 D6 D5D4D3 D2 D1D0
//------------------------------------------------
//(1).D7D6
// 无意义
//(2).D5D4D3:奇偶检验设置.
// 000/010/100/110 无奇偶检验
// 001 奇检验
// 011 偶检验
// 101 标志(MARK)奇偶检验
// 111 空白(SPACE)奇偶检验
//(3).D2:停止位设置.
// 当该位为0时,停止位数为1位;
// 该位为1时,且D1D0=00时,停止位为1.5.
// 该位为1时,且D1D0<>00时,停止位为2.
//(4).D1D0:数据位位数
// 00 数据位数=5
// 01 数据位数=6
// 10 数据位数=7
// 11 数据位数=8
//
void MSCOM_Init(unsigned int COM,unsigned char BAUD,unsigned char STOP,unsigned char UPM)
{
unsigned char setting;
unsigned char Dll;
unsigned char Dlh;
unsigned char c;
switch (BAUD)
{
case BAUD_1200:
Dll = 0x60;
Dlh = 0x00;
break;
case BAUD_2400:
Dll = 0x30;
Dlh = 0x00;
break;
case BAUD_4800:
Dll = 0x18;
Dlh = 0x00;
break;
case BAUD_9600:
Dll = 0x0C;
Dlh = 0x00;
break;
case BAUD_14400:
Dll = 0x08;
Dlh = 0x00;
break;
case BAUD_19200:
Dll = 0x06;
Dlh = 0x00;
break;
case BAUD_38400:
Dll = 0x03;
Dlh = 0x00;
break;
case BAUD_57600:
Dll = 0x02;
Dlh = 0x00;
break;
case BAUD_115200:
Dll = 0x01;
Dlh = 0x00;
break;
default:
Dll = 0x0C;
Dlh = 0x00;
break;
}
setting = 0x03; // 数据位=8位
switch (STOP)
{
// case STOP_1:
// setting &= ~0x04;
// break;
case STOP_2:
setting |= 0x04;
break;
}
switch (UPM)
{
// case NONE_PARITY:
// setting &= ~0x38;
// break;
case ODD_PARITY: //j
setting |= 0x08;
break;
case EVEN_PARITY: //o
setting |= 0x18;
break;
}
switch (COM)
{
case COM1: // 0x03F8 ---> BIOS-COM1
c = inportb((unsigned int)COM1_BASE + LCR);
outportb((unsigned int)COM1_BASE + LCR , c | 0x80);
outportb((unsigned int)COM1_BASE + DLL , Dll);
outportb((unsigned int)COM1_BASE + DLH , Dlh);
outportb((unsigned int)COM1_BASE + LCR , c);
outportb((unsigned int)COM1_BASE + LCR , setting);
break;
case COM2: // 0x02F8 ---> BIOS-COM2
c = inportb((unsigned int)COM2_BASE + LCR);
outportb((unsigned int)COM2_BASE + LCR , c | 0x80);
outportb((unsigned int)COM2_BASE + DLL , Dll);
outportb((unsigned int)COM2_BASE + DLH , Dlh);
outportb((unsigned int)COM2_BASE + LCR , c);
outportb((unsigned int)COM2_BASE + LCR , setting);
break;
case COM3: // 0x0300 ---> PCM3614-COM1
c = inportb((unsigned int)COM3_BASE + LCR);
outportb((unsigned int)COM3_BASE + LCR , c | 0x80);
outportb((unsigned int)COM3_BASE + DLL , Dll);
outportb((unsigned int)COM3_BASE + DLH , Dlh);
outportb((unsigned int)COM3_BASE + LCR , c);
outportb((unsigned int)COM3_BASE + LCR , setting);
break;
case COM4: // 0x0308 ---> PCM3614-COM2
c = inportb((unsigned int)COM4_BASE + LCR);
outportb((unsigned int)COM4_BASE + LCR , c | 0x80);
outportb((unsigned int)COM4_BASE + DLL , Dll);
outportb((unsigned int)COM4_BASE + DLH , Dlh);
outportb((unsigned int)COM4_BASE + LCR , c);
outportb((unsigned int)COM4_BASE + LCR , setting);
break;
case COM5: // 0x0310 ---> PCM3614-COM3
c = inportb((unsigned int)COM5_BASE + LCR);
outportb((unsigned int)COM5_BASE + LCR , c | 0x80);
outportb((unsigned int)COM5_BASE + DLL , Dll);
outportb((unsigned int)COM5_BASE + DLH , Dlh);
outportb((unsigned int)COM5_BASE + LCR , c);
outportb((unsigned int)COM5_BASE + LCR , setting);
break;
case COM6: // 0x0318 ---> PCM3614-COM4
c = inportb((unsigned int)COM6_BASE + LCR);
outportb((unsigned int)COM6_BASE + LCR , c | 0x80);
outportb((unsigned int)COM6_BASE + DLL , Dll);
outportb((unsigned int)COM6_BASE + DLH , Dlh);
outportb((unsigned int)COM6_BASE + LCR , c);
outportb((unsigned int)COM6_BASE + LCR , setting);
break;
}
}
void USART_Send_Char(unsigned int COM,unsigned char ch)
{
switch (COM)
{
case COM1: // 0x03F8 ---> BIOS-COM1
while ((inportb((unsigned int)COM1_BASE + LSR) & 0x20) == 0) ;
outportb((unsigned int)COM1_BASE + TXR , ch);
break;
case COM2: // 0x02F8 ---> BIOS-COM2
while ((inportb((unsigned int)COM2_BASE + LSR) & 0x20) == 0) ;
outportb((unsigned int)COM2_BASE + TXR , ch);
break;
case COM3: // 0x0300 ---> PCM3614-COM1
while ((inportb((unsigned int)COM3_BASE + LSR) & 0x20) == 0) ;
outportb((unsigned int)COM3_BASE + TXR , ch);
break;
case COM4: // 0x0308 ---> PCM3614-COM2
while ((inportb((unsigned int)COM4_BASE + LSR) & 0x20) == 0) ;
outportb((unsigned int)COM4_BASE + TXR , ch);
break;
case COM5: // 0x0310 ---> PCM3614-COM3
while ((inportb((unsigned int)COM5_BASE + LSR) & 0x20) == 0) ;
outportb((unsigned int)COM5_BASE + TXR , ch);
break;
case COM6: // 0x0318 ---> PCM3614-COM4
while ((inportb((unsigned int)COM6_BASE + LSR) & 0x20) == 0) ;
outportb((unsigned int)COM6_BASE + TXR , ch);
break;
}
}
/
// set Timer interrupt vect
/
void SetTimer_Vect(void)
{
timer_old_vect = getvect(0x1C);
setvect(0x1C, timer_int);
}
/
// restore Timer interrupt vect
/
void RestoreTimer_Vect(void)
{
setvect(0x1C, timer_old_vect);
}
void SetVectInit(void)
{
unsigned char i;
SetTimer_Vect();
for (i = COM1 ; i <= COM6 ; i++)
SetSerial_Vect(i);
}
void RestoreVectInit(void)
{
unsigned char i;
RestoreTimer_Vect();
for (i = COM1 ; i <= COM6 ; i++)
RestoreSerial_Vect(i);
}
///
//COM1 Interrupt Server Program (BIOS-COM1)
///
void far interrupt com1_vect(void)
{
unsigned char ch;
unsigned char val;
val = inportb((unsigned int)COM1_BASE + IIR) & IIR_MASK;
switch (val)
{
case IIR_RX_ID:
ch = inportb((unsigned int)COM1_BASE + RXR);
if (USART1_receCount < MSCOMM_BUFFER_LENGTH)
USART1_mscomm_buffer[USART1_receCount++] = ch;
USART1_receTimeOut = 2;
break;
case IIR_TX_ID:
if (USART1_sendPosi < USART1_sendCount)
outportb((unsigned int)COM1_BASE + TXR , USART1_send_buffer[USART1_sendPosi++]);
else
outportb((unsigned int)COM1_BASE + IER , IER_RX_INT);
break;
}
outportb(INTC_EOI,IRQ_EOI);
}
///
//COM2 Interrupt Server Program (BIOS-COM2)
///
void far interrupt com2_vect(void)
{
unsigned char ch;
unsigned char val;
val = inportb((unsigned int)COM2_BASE + IIR) & IIR_MASK;
switch (val)
{
case IIR_RX_ID:
ch = inportb((unsigned int)COM2_BASE + RXR);
if (USART2_receCount < MSCOMM_BUFFER_LENGTH)
USART2_mscomm_buffer[USART2_receCount++] = ch;
USART2_receTimeOut = 2;
break;
case IIR_TX_ID:
if (USART2_sendPosi < USART2_sendCount)
outportb((unsigned int)COM2_BASE + TXR , USART2_send_buffer[USART2_sendPosi++]);
else
outportb((unsigned int)COM2_BASE + IER , IER_RX_INT);
break;
}
outportb(INTC_EOI,IRQ_EOI);
}
///
//COM3 Interrupt Server Program (PCM-3614-COM1)
///
void far interrupt com3_vect(void)
{
unsigned char ch;
unsigned char val;
val = inportb((unsigned int)COM3_BASE + IIR) & IIR_MASK;
switch (val)
{
case IIR_RX_ID:
ch = inportb((unsigned int)COM3_BASE + RXR);
if (USART3_receCount < MSCOMM_BUFFER_LENGTH)
USART3_mscomm_buffer[USART3_receCount++] = ch;
USART3_receTimeOut = 2;
break;
case IIR_TX_ID:
if (USART3_sendPosi < USART3_sendCount)
outportb((unsigned int)COM3_BASE + TXR , USART3_send_buffer[USART3_sendPosi++]);
else
outportb((unsigned int)COM3_BASE + IER , IER_RX_INT);
break;
}
outportb(INTC_EOI,IRQ_EOI);
}
///
//COM4 Interrupt Server Program (PCM-3614-COM2)
///
void far interrupt com4_vect(void)
{
unsigned char ch;
unsigned char val;
val = inportb((unsigned int)COM4_BASE + IIR) & IIR_MASK;
switch (val)
{
case IIR_RX_ID:
ch = inportb((unsigned int)COM4_BASE + RXR);
if (USART4_receCount < MSCOMM_BUFFER_LENGTH)
USART4_mscomm_buffer[USART4_receCount++] = ch;
USART4_receTimeOut = 2;
break;
case IIR_TX_ID:
if (USART4_sendPosi < USART4_sendCount)
outportb((unsigned int)COM4_BASE + TXR , USART4_send_buffer[USART4_sendPosi++]);
else
outportb((unsigned int)COM4_BASE + IER , IER_RX_INT);
break;
}
outportb(INTC_EOI,IRQ_EOI);
}
///
//COM5 Interrupt Server Program (PCM-3614-COM3)
///
void far interrupt com5_vect(void)
{
unsigned char ch;
unsigned char val;
val = inportb((unsigned int)COM5_BASE + IIR) & IIR_MASK;
switch (val)
{
case IIR_RX_ID:
ch = inportb((unsigned int)COM5_BASE + RXR);
if (USART5_receCount < MSCOMM_BUFFER_LENGTH)
USART5_mscomm_buffer[USART5_receCount++] = ch;
USART5_receTimeOut = 2;
break;
case IIR_TX_ID:
if (USART5_sendPosi < USART5_sendCount)
outportb((unsigned int)COM5_BASE + TXR , USART5_send_buffer[USART5_sendPosi++]);
else
outportb((unsigned int)COM5_BASE + IER , IER_RX_INT);
break;
}
outportb(INTC_EOI,IRQ_EOI);
}
///
//COM6 Interrupt Server Program (PCM-3614-COM4)
///
void far interrupt com6_vect(void)
{
unsigned char ch;
unsigned char val;
val = inportb((unsigned int)COM6_BASE + IIR) & IIR_MASK;
switch (val)
{
case IIR_RX_ID:
ch = inportb((unsigned int)COM6_BASE + RXR);
if (USART6_receCount < MSCOMM_BUFFER_LENGTH)
USART6_mscomm_buffer[USART6_receCount++] = ch;
USART6_receTimeOut = 2;
break;
case IIR_TX_ID:
if (USART6_sendPosi < USART6_sendCount)
outportb((unsigned int)COM6_BASE + TXR , USART6_send_buffer[USART6_sendPosi++]);
else
outportb((unsigned int)COM6_BASE + IER , IER_RX_INT);
break;
}
outportb(0xA0,0x20);
outportb(INTC_EOI,IRQ_EOI);
}
///
//SOFT-Timer Interrupt Server Program
///
void far interrupt timer_int(void)
{
USART1_Time_Run();
USART2_Time_Run();
USART3_Time_Run();
USART4_Time_Run();
USART5_Time_Run();
USART6_Time_Run();
outportb(INTC_EOI,IRQ_EOI);
}
void main(void)
{
outportb(0x20,0x20);
outportb(0x21,0x00);
outportb(0xa0,0x20);
outportb(0xa1,0x00);
disable();
SetVectInit();
OpenSerial(COM1 , COM1_IRQ - 8 , MODBUS_Baud,MODBUS_STOP,MODBUS_UPM);
OpenSerial(COM2 , COM2_IRQ - 8 , MODBUS_Baud,MODBUS_STOP,MODBUS_UPM);
OpenSerial(COM3 , COM3_IRQ - 8 , MODBUS_Baud,MODBUS_STOP,MODBUS_UPM);
OpenSerial(COM4 , COM4_IRQ - 8 , MODBUS_Baud,MODBUS_STOP,MODBUS_UPM);
OpenSerial(COM5 , COM5_IRQ - 8 , MODBUS_Baud,MODBUS_STOP,MODBUS_UPM);
OpenSerial(COM6 , COM6_IRQ - 8 , MODBUS_Baud,MODBUS_STOP,MODBUS_UPM);
enable();
while (1)
{
USART1_Modbus_Analyze();
USART2_Modbus_Analyze();
USART3_Modbus_Analyze();
USART4_Modbus_Analyze();
USART5_Modbus_Analyze();
USART6_Modbus_Analyze();
}
disable();
RestoreVectInit();
CloseSerial(COM1,COM1_IRQ - 8);
CloseSerial(COM2,COM2_IRQ - 8);
CloseSerial(COM3,COM3_IRQ - 8);
CloseSerial(COM4,COM4_IRQ - 8);
CloseSerial(COM5,COM5_IRQ - 8);
CloseSerial(COM6,COM6_IRQ - 8);
enable();
}