📄 modem.c
字号:
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define COM1 1
#define COM2 2
#define COM3 3
#define COM4 4
#define COM1BASE 0x3F8 // Base port address for COM1
#define COM2BASE 0x2F8 // Base port address for COM2
#define COM3BASE 0x3E8 // Base port address for COM3
#define COM4BASE 0x2E8 // Base port address for COM4
//////////////////////////////////////////////////////////////////////
//
//-------------------------------------------------------------------
// The 8250 UART has 10 registers accessible through 7 port addresses.
// Here are their addresses relative to COM1BASE and COM2BASE. Note
// that the baud rate registers, (DLL) and (DLH) are active only when
// the Divisor-Latch Access-Bit (DLAB) is on. The (DLAB) is bit 7 of
// the (LCR).
// o TXR Output data to the serial port.
// o RXR Input data from the serial port.
// o LCR Initialize the serial port.
// o IER Controls interrupt generation.
// o IIR Identifies interrupts.
// o MCR Send contorl signals to the modem.
// o LSR Monitor the status of the serial port.
// o MSR Receive status of the modem.
// o DLL Low byte of baud rate divisor.
// o DHH High byte of baud rate divisor.
//-------------------------------------------------------------------
#define TXR 0 // Transmit register (WRITE)
#define RXR 0 // Receive register (READ)
#define IER 1 // Interrupt Enable
#define IIR 2 // Interrupt ID
#define LCR 3 // Line control
#define MCR 4 // Modem control
#define LSR 5 // Line Status
#define MSR 6 // Modem Status
#define DLL 0 // Divisor Latch Low
#define DLH 1 // Divisor latch High
#define FCR 2 // Interrupt ID
//-------------------------------------------------------------------
// Bit values held in the Line Control Register (LCR).
// bit meaning
// --- -------
// 0-1 00=5 bits, 01=6 bits, 10=7 bits, 11=8 bits.
// 2 Stop bits.
// 3 0=parity off, 1=parity on.
// 4 0=parity odd, 1=parity even.
// 5 Sticky parity.
// 6 Set break.
// 7 Toggle port addresses.
//-------------------------------------------------------------------
#define NO_PARITY 0x00
#define EVEN_PARITY 0x18
#define ODD_PARITY 0x08
//-------------------------------------------------------------------
// Bit values held in the Line Status Register (LSR).
// bit meaning
// --- -------
// 0 Data ready.
// 1 Overrun error - Data register overwritten.
// 2 Parity error - bad transmission.
// 3 Framing error - No stop bit was found.
// 4 Break detect - End to transmission requested.
// 5 Transmitter holding register is empty.
// 6 Transmitter shift register is empty.
// 7 Time out - off line.
//-------------------------------------------------------------------
#define RCVRDY 0x01
//#define OVRERR 0x02
//#define PRTYERR 0x04
//#define FRMERR 0x08
//#define BRKERR 0x10
//#define XMTRDY 0x20
//#define XMTRSR 0x40
//#define TIMEOUT 0x80
//-------------------------------------------------------------------
// Bit values held in the Modem Output Control Register (MCR).
// bit meaning
// --- -------
// 0 Data Terminal Ready. Computer ready to go.
// 1 Request To Send. Computer wants to send data.
// 2 auxillary output #1.
// 3 auxillary output #2.(Note: This bit must be
// set to allow the communications card to send
// interrupts to the system)
// 4 UART ouput looped back as input.
// 5-7 not used.
//-------------------------------------------------------------------
#define DTR 0x01
#define RTS 0x02
#define MC_INT 0x08
int portbase = 0;
int port = COM1;
int speed = 9600;
int parity = NO_PARITY;
int bits = 8;
int stopbits = 1;
///////////////////////////////////////////////////////////////////////////////
// read one char from receive FIFO
//return ==0 mean read one char and in unsigned char *uc
// ==-1 mean read nothing
int SerialInChar(unsigned char *uc)
{
if (( inportb(portbase + LSR) & RCVRDY))
{// Received data available
*uc=inportb(portbase);
return 1;
}
else
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// clear receive FIFO and Transmit FIFO
void ClearFIFO(void)
{
int i;
unsigned char uc;
outportb(portbase + FCR , 0xC7); // FIFO Control Register
for(i=0;i<500;i++)
{
SerialInChar(&uc);
// delay(10);
}
}
///////////////////////////////////////////////////////////////////////////////
//read all char from receive FIFO within about 5 second
//parameters: char *flag is string
//return length of str
int CheckReply(char *str)
{
int i,j;
unsigned char uc;
j=0;
for(i=0;i<1000;i++)
{
if(SerialInChar(&uc)==1)
{
if((uc==0x0d)||(uc==0x0a)) continue;
*(str+j)=uc;
j++;
}
delay(10);
}
return (j);
}
///////////////////////////////////////////////////////////////////////////////
// Output a character to the serial port
void SerialOut(char x)
{
outportb(portbase + TXR, x);
}
///////////////////////////////////////////////////////////////////////////////
// Set the port number to use
int SetPort(int Port)
{
int Offset, far *RS232_Addr;
switch (Port)
{// Sort out the base address
case COM1 : Offset = 0x0000;
break;
case COM2 : Offset = 0x0002;
break;
case COM3 : Offset = 0x0004;
break;
case COM4 : Offset = 0x0006;
break;
default : return (-1);
}
RS232_Addr = (int far *)MK_FP(0x0040, Offset); // Find out where the port is.
if (*RS232_Addr == NULL) return (-1);// If NULL then port not used.
portbase = *RS232_Addr; // Otherwise set portbase
return (0);
}
///////////////////////////////////////////////////////////////////////////////
// This routine sets the speed; will accept funny baud rates.
// Setting the speed requires that the DLAB be set on.
int SetSpeed(int Speed)
{
char c;
int divisor;
if (Speed == 0) // Avoid divide by zero
return (-1);
else
divisor = (int) (115200L/Speed);
if (portbase == 0)
return (-1);
disable();
c = inportb(portbase + LCR);
outportb(portbase + LCR, (c | 0x80)); // Set DLAB
outportb(portbase + DLL, (divisor & 0x00FF));
outportb(portbase + DLH, ((divisor >> 8) & 0x00FF));
outportb(portbase + LCR, c); // Reset DLAB
enable();
return (0);
}
///////////////////////////////////////////////////////////////////////////////
// Set other communications parameters
int SetOthers(int Parity, int Bits, int StopBit)
{
int setting;
if (portbase == 0) return (-1);
if (Bits < 5 || Bits > 8) return (-1);
if (StopBit != 1 && StopBit != 2) return (-1);
if (Parity != NO_PARITY && Parity != ODD_PARITY && Parity != EVEN_PARITY)
return (-1);
setting = Bits-5;
setting |= ((StopBit == 1) ? 0x00 : 0x04);
setting |= Parity;
disable();
outportb(portbase + LCR, setting);
enable();
return (0);
}
void ReadModemPara(void)
{
char readbuf[260],buf[18];
char *endptr;
int i,j;
FILE *fp;
fp=fopen("hjwmodem.ini","rt");
if(fp!=NULL)
{
while(fgets(readbuf,260,fp)!=NULL)
{
i = sscanf(readbuf,"PORT:%s\n",buf);
if ((i != 0)&&(i != EOF))
{
if (stricmp(buf,"COM1") == 0) port = COM1;
else
{
if (stricmp(buf,"COM2") == 0) port = COM2;
else
{
if (stricmp(buf,"COM3") == 0) port = COM3;
else
{
if (stricmp(buf,"COM4") == 0) port = COM4;
}
}
}
}
i = sscanf(readbuf,"BAUD:%s\n",buf);
if ((i != 0)&&(i != EOF))
speed = (int)strtol(buf,&endptr,10);
i = sscanf(readbuf,"PARITY:%s\n",buf);
if ((i != 0)&&(i != EOF))
{
if (stricmp(buf,"NO") == 0) parity = NO_PARITY;
else
{
if (stricmp(buf,"EVEN") == 0) parity = EVEN_PARITY;
else
{
if (stricmp(buf,"ODD") == 0) parity = ODD_PARITY;
}
}
}
i = sscanf(readbuf,"BITS:%s\n",buf);
if ((i != 0)&&(i != EOF))
bits = (int)strtol(buf,&endptr,10);
i = sscanf(readbuf,"STOPBITS:%s\n",buf);
if ((i != 0)&&(i != EOF))
stopbits = (int)strtol(buf,&endptr,10);
// i = sscanf(readbuf,"TELEPHONE:%s\n",buf);
// if ((i != 0)&&(i != EOF))
// strcpy(tele,buf);
}
fclose(fp);
}
}
///////////////////////////////////////////////////////////////////////////////
// initialize serial port
// return ==0 mean initialized OK
// ==-1 mean initialized ERROR
int InitialSerial(void)
{
int flag = 0;
ReadModemPara(); //read parameters from file "hjwmodem.ini"
if (SetPort(port)) flag = -1; //get baseaddress of COM
outportb(portbase + 1 , 0); // Turn off interrupts
if (SetSpeed(speed)) flag = -1; // Set speed for COM
if (SetOthers(parity, bits, stopbits)) flag = -1;
outportb(portbase + FCR , 0xC7); // FIFO Control Register
// ClearFIFO();
outportb(portbase + MCR, DTR | RTS | MC_INT); // Turn on DTR, RTS, and OUT2
if (!flag) return (0);
else return (-1);
}
void Command(char *str)
{
int i,j;
i=strlen(str);
for(j=0;j<i;j++)
{
SerialOut(*(str+j));
}
}
///////////////////////////////////////////////////////////////////////////////
// dial modem
void DialTel(char *tel)
{
char TelStr[68];
memset(TelStr,0,68);
strcpy(TelStr,"ATDT");
strcat(TelStr,tel);
strcat(TelStr,";\r");
// strcat(TelStr,"\r");
Command(TelStr);
}
///////////////////////////////////////////////////////////////////////////////
// hang up modem
void HangUp(void)
{
Command("ATH0;\r");
}
///////////////////////////////////////////////////////////////////////////////
// reset modem
void ResetModem(void)
{
Command("ATZ;\r"); //reset modem
delay(1000);
Command("ATE0;\r"); //echo off
// delay(100);
Command("ATQ0;\r"); //modem echo result code
// delay(100);
Command("ATV1;\r"); //modem echo result code with strings
delay(1000);
// ClearFIFO();
}
/*
void main()
{
// Default communications parameters
int done = 0;
char c;
int i,j;
unsigned char c1;
printf("%d \n",initial_serial());
fprintf(stdout, "press [ESC] to quit...\n\n");
ResetModem();
ClearFIFO();
DialTel(tele);
for(i=0;i<500;i++)
{
if(SerialInChar(&c1)==1) printf("%c",c1);
delay(10);
}
HangUp();
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -