| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1573 人关注过本帖
标题:请求帮助:修改C程序使之在VC++6.0下编译运行
只看楼主 加入收藏
li343
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2009-10-9
结帖率:0
收藏
已结贴  问题点数:10 回复次数:4 
请求帮助:修改C程序使之在VC++6.0下编译运行
0603.rar (18.47 KB)


请高手帮忙修改一下这段串口通信程序,使之能够在VC下编译运行。程序代码见附件0603.rar。


程序代码:
/*---------------------------------------------------------------------
   FILENAME: GSERIAL.H
   This file is used to define const and class for GSERIAL.CPP
   此文件用于定义常量和serial类的变量
--------------------------------------------------------------------*/

#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>


//Define Serial port Const 定义串口逻辑名常量
#define COM1            1
#define COM2            2
#define COM3            3
#define COM4            4
#define COM5            5
#define COM6            6

#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  */
#define COM5BASE        0x3A8   /*  Base port address for COM5  */
#define COM6BASE        0x2A8   /*  Base port address for COM6  */

/*
    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--Line Control Register线路控制寄存器).

    * TXR Output data to the serial port.
    * RXR Input data from the serial port.
    * LCR Initialize the serial port.
    * IER Controls interrupt generation.
    * IIR Identifies interrupts.
    * MCR Send contorl signals to the modem.
    * LSR Monitor the status of the serial port.
    * MSR Receive status of the modem.
    * DLL Low byte of baud rate divisor.
    * DHH High byte of baud rate divisor.
*/

/*The following is the adress of the registers               DLAB status    */
#define TXR             0       /*  Transmit register (WRITE)   0            */
#define RXR             0       /*  Receive register  (READ)    0            */
#define IER             1       /*  Interrupt Enable            x            */
#define IIR             2       /*  Interrupt ID                x            */
#define LCR             3       /*  Line control                x            */
#define MCR             4       /*  Modem control                x            */
#define LSR             5       /*  Line Status                    x            */
#define MSR             6       /*  Modem Status                x            */

#define DLL             0       /*  Divisor Latch Low            1            */
#define DLH             1       /*  Divisor latch High            1            */


/*-------------------------------------------------------------------*
  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.    /word length select bit
    2        Stop bits.                                    /    
    3        0=parity off, 1=parity on.                    /Parity Enable=1
    4        0=parity odd, 1=parity even.                /Odd or Even select
    5        Sticky parity.                                /
    6        Set break.
    7        Toggle port addresses.                        /1:access 
 *-------------------------------------------------------------------*/
#define LCR_NO_PARITY       0x00
#define LCR_EVEN_PARITY     0x18
#define LCR_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 LSR_RCVRDY          0x01
#define LSR_OVRERR          0x02
#define LSR_PRTYERR         0x04
#define LSR_FRMERR          0x08
#define LSR_BRKERR          0x10
#define LSR_XMTRDY          0x20
#define LSR_XMTRSR          0x40
#define LSR_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 MCR_DTR             0x01
#define MCR_RTS             0x02
#define MCR_INT                0x08


/*------------------------------------------------------------------*
  Bit values held in the Modem Input Status Register (MSR).
    bit        meaning
    ---        -------
    0        delta Clear To Send.
    1        delta Data Set Ready.
    2        delta Ring Indicator.
    3        delta Data Carrier Detect.
    4        Clear To Send.
    5        Data Set Ready.
    6        Ring Indicator.
    7        Data Carrier Detect.
 *------------------------------------------------------------------*/
#define MSR_CTS             0x10
#define MSR_DSR             0x20


/*------------------------------------------------------------------*
  Bit values held in the Interrupt Enable Register (IER).
    bit        meaning
    ---        -------
    0        Interrupt when data received.
    1        Interrupt when transmitter holding reg. empty.
    2        Interrupt when data reception error.
    3        Interrupt when change in modem status register.
    4-7        Not used.
 *------------------------------------------------------------------*/
#define IER_RX_INT          0x01
#define IER_TX_INT          0x02


/*------------------------------------------------------------------*
  Bit values held in the Interrupt Identification Register (IIR).
    bit        meaning
    ---        -------
    0        Interrupt pending
    1-2             Interrupt ID code
            00=Change in modem status register,
            01=Transmitter holding register empty,
            10=Data received,
            11=reception error, or break encountered.
    3-7        Not used.
 *------------------------------------------------------------------*/
#define IIR_MS_ID           0x00   // Modem status
#define IIR_RX_ID           0x04   // Rceived data OK,and to read the receive buffer
#define IIR_TX_ID           0x02   // Transmitter holding register empty
#define IIR_MASK            0x07   // Get the low 3 bits of IIR 


/*
    These are the port addresses of the 8259 Programmable Interrupt
    Controller (PIC).
*/
#define PIC8259_IMR             0x21   /* Interrupt Mask Register port */
#define PIC8259_ICR             0x20   /* Interrupt Control Port       */


/*
    An end of interrupt needs to be sent to the Control Port of
    the 8259 when a hardware interrupt ends.
*/
#define PIC8259_EOI            0x20   /* End Of Interrupt */




/*
    The (IMR) tells the (PIC) to service an interrupt only if it
    is not masked (FALSE).
*/
#define IRQ0            0xFE  // COM? 1111 1110
#define IRQ1            0xFD  // COM? 1111 1101
#define IRQ2            0xFB  // COM? 1111 1011
#define IRQ3            0xF7  // COM2 1111 0111  /* COM2 */
#define IRQ4            0xEF  // COM1 1110 1111  /* COM1 */
#define IRQ5            0xDF  // COM? 1101 1111 
#define IRQ6            0xBF  // COM? 1011 1111
#define IRQ7            0x7F  // COM? 0111 1111

#define IRQ8            0xFE  // COM? 1111 1110
#define IRQ9            0xFD  // COM? 1111 1101
#define IRQ10           0xFB  // COM? 1111 1011
#define IRQ11           0xF7  // COM? 1111 0111
#define IRQ12           0xEF  // COM? 1110 1111
#define IRQ13           0xDF  // COM? 1101 1111 
#define IRQ14           0xBF  // COM? 1011 1111
#define IRQ15           0x7F  // COM? 0111 1111


#define FALSE                0
#define TRUE                1

#define ESC                    0x1B    /* ASCII Escape character */
#define ASCII                0x007F  /* Mask ASCII characters  */


#define NO_ERROR            0       /* 无错误No error               */

#define BUF_OVFL            1       /* 缓冲区溢出Buffer overflowed      */

#define SBUFSIZ                512     /* Serial buffer size     */
#define IBUF_LEN            2048    // 接收缓冲区Incoming buffer
#define OBUF_LEN            1024    // 发送缓冲区Outgoing buffer

    unsigned int PortBaseAddr[6]= {COM1BASE,COM2BASE,COM3BASE,COM4BASE,COM5BASE,COM6BASE};

    // 70-8  71-9  72-10  73-11  74-12  75-13 76-14 77-15
    int InterruptNo[6]=  { 0x0C, 0x0B, 0x0D,  0x72,  0x73,  0x77};//4,3,5,10,11,15
    int ComIRQ[6] =     { IRQ4, IRQ3, IRQ5,  IRQ10, IRQ11, IRQ15};


///////////////////////
 class GSerial{
    int flag;

public:

    unsigned int   m_unPortNo;
    unsigned int   m_unPortBase;
    GSerial(void);
    ~GSerial(void);

    int  InitSerialPort(int Port, int Speed, int Parity, int Bits, int StopBit);
    void CloseSerialPort(void);
    int  SetDataFormat(int Parity, int Bits, int StopBit);
    int  SetSpeed(int Speed);
    int  SetPortBaseAddr(int Port);
    void CommOn(void);
    void CommOff(void);

    int ReadStatus(void);
    void SendChar(unsigned char unCh);
    void SendString(int nStrlen, unsigned char *unChBuf);
    //char ReadChar(void);

    void interrupt(*OldVects)(...);

    void SetVects(void interrupt(*New_Int)(...));
    void ResetVects(void);

};






程序代码:
/*------------------------------------------------------------------*
      GSERIAL.CPP

      For asynchronous serial port communications
      适用于DOS环境下异步串口通信编程

      ATTENTION: Compile this program with Test Stack Overflow OFF.
    在Turbo C++3.0中选项设置 Options/Compiler/Entry中关闭Test Stack Overflow

*------------------------------------------------------------------*/

#include "GSerial.h"


    char  inbuf[IBUF_LEN];        // 接受数据buffer
    char  outbuf[OBUF_LEN];        // 发送数据buffer

/* 串口基地址数据缓冲区有关变量 */
    unsigned int   startbuf = 0;
    unsigned int   endbuf  = 0;
    unsigned int   inhead  = 0;
    unsigned int   intail   = 0;
    unsigned int   outhead  = 0;
    unsigned int   outtail  = 0;

/* 串口基地址 */
    unsigned int   PortBase = 0;

GSerial::GSerial()
{
}

GSerial::~GSerial()
{
}

/*  读取串口LSR状态  */
int GSerial::ReadStatus(void)
{
  return(inp(m_unPortBase+5));
}

/* 发送一个字符  */
void GSerial::SendChar(unsigned char unCh)
{
   while ((ReadStatus() & 0x40) == 0);
   outportb(m_unPortBase,unCh);
}

/*  发送一个字符串  */
void GSerial::SendString(int nStrlen, unsigned char *unChBuf)
{
    int k=0;    
    do {
        SendChar(*(unChBuf + k));    
        k++;
    } while ((k < nStrlen));
}


/* 装入新的中断向量:中断服务程序地址 */
void GSerial::SetVects(void interrupt(*New_Int)(...))
{
    disable();
    OldVects = getvect(InterruptNo[m_unPortNo-1]);
    setvect(InterruptNo[m_unPortNo-1], New_Int);
    enable();
}

/* 恢复中断向量 */
void GSerial::ResetVects(void)
{
    setvect(InterruptNo[m_unPortNo-1], OldVects);
}



/* 启动串口 */
void GSerial::CommOn(void)
{
    int temp;
    disable();
    //temp = inportb(m_unPortBase + MCR) | MCR_INT;
    //outportb(m_unPortBase + MCR, temp);
    outportb(m_unPortBase + MCR, MCR_INT);
    //temp = inportb(m_unPortBase + MCR) | MCR_DTR | MCR_RTS;
    //outportb(m_unPortBase + MCR, temp);
    temp = (inportb(m_unPortBase + IER)) | IER_RX_INT;//|IER_TX_INT;
    outportb(m_unPortBase + IER, temp);
    temp = inportb(PIC8259_IMR) & ComIRQ[m_unPortNo-1];
    outportb(PIC8259_IMR, temp);
    enable();
}

/* 关闭串口 */
void GSerial::CommOff(void)
{
     int  temp;

    disable();
    temp = inportb(PIC8259_IMR) | ~ComIRQ[m_unPortNo-1];
    outportb(PIC8259_IMR, temp);
    outportb(m_unPortBase + IER, 0);
    outportb(m_unPortBase + MCR, 0);
    enable();
}



/* 设置串口号 */
int GSerial::SetPortBaseAddr(int Port)
{
    if((Port<1)||(Port>6))
        return(-1);
    m_unPortNo = Port;
    m_unPortBase = PortBaseAddr[m_unPortNo-1];
    return (0);
}

/* 设置波特率 */
/* Setting the speed requires that the DLAB be set on.        */
int GSerial::SetSpeed(int Speed)
{
    char    c;
    int        divisor;

    if (Speed == 0)            /* Avoid divide by zero */
        return (-1);
    else
        divisor = (int) (115200L/Speed);

    if (m_unPortBase == 0)
        return (-1);

    disable();
    c = inportb(m_unPortBase + LCR);
    outportb(m_unPortBase + LCR, (c | 0x80)); /* Set DLAB */
    outportb(m_unPortBase + DLL, (divisor & 0x00FF));
    outportb(m_unPortBase + DLH, ((divisor >> 8) & 0x00FF));
    outportb(m_unPortBase + LCR, c);          /* Reset DLAB */
    enable();

    return (0);
}

/* S设置数据格式:奇偶较验,数据位,停止位 */
int GSerial::SetDataFormat(int Parity, int Bits, int StopBit)
{
    int  setting;

    if (m_unPortBase == 0)
        return (-1);
    if (Bits < 5 || Bits > 8)
        return (-1);
    if (StopBit != 1 && StopBit != 2)
        return (-1);
    if (Parity != LCR_NO_PARITY && Parity != LCR_ODD_PARITY && Parity != LCR_EVEN_PARITY)
        return (-1);

    setting  = Bits-5;
    setting |= ((StopBit == 1) ? 0x00 : 0x04);
    setting |= Parity;

    disable();
    outportb(m_unPortBase + LCR, setting);
    enable();

    return (0);
}

/* 关闭串口*/
void GSerial::CloseSerialPort(void)
{
    CommOff();
    ResetVects();  /* 恢复中断向量 */
}

/* 初始化串口:设置串口号,数据格式 */
int GSerial::InitSerialPort(int Port, int Speed, int Parity, int Bits, int StopBit)
{
    int flag = 0;
    if (SetPortBaseAddr(Port))
      flag = -1;
    if (SetSpeed(Speed))
      flag = -1;
    if (SetDataFormat(Parity, Bits, StopBit))
      flag = -1;
    return(flag);
}

/* 本函数非GSerial类成员函数 */
void interrupt ComIntServ(...)
{
    int temp;
    disable();
    temp = (inportb(PortBase+IIR)) & IIR_MASK;                // why interrupt was called
    switch(temp)
    {
        case 0x00:  // modem status changed
            inportb(PortBase+MSR);   // read in useless char
            break;
        case 0x02:  // 可以发送数据Request To Send char
            if (outhead != outtail)                            // 数据要发送there's a char to send
            {
                outportb(PortBase+TXR,outbuf[outhead++]);    // send the character
                if (outhead == OBUF_LEN)
                    outhead=0;                                // if at end of buffer, reset pointer
            }
            break;
        case 0x04:  // 串口接收器中有数据character ready to be read in
            //inbuf[inhead++] = inportb(m_unPortBase+RXR);// read character into inbuffer
            inbuf[inhead] = inportb(PortBase+RXR);// 读取字符数据read character into inbuffer
            inhead++;
            if (inhead == IBUF_LEN) // if at end of buffer
                inhead=0;           // reset pointer
            break;
        case 0x06:  // line status has changed
            inportb(PortBase+LSR);     // read in useless char
            break;
        default:
            break;

    }

    outportb(PIC8259_ICR, PIC8259_EOI);    // 硬件中断结束Signal end of hardware interrupt
    enable();                            // reenable interrupts at the end of the handler

}

/* 本函数也不是GSerial类成员函数,是笔者为了多串口编程而设计的 */
char ReadChar(void)
{
    char ch;
    if (inhead != intail)     // there is a character
    {
        disable();                          // disable irqs while getting char
        ch = inbuf[intail++];               // get character from buffer
        if (intail == IBUF_LEN)                // if at end of in buffer
            intail=0;                        // reset pointer
        enable();                           // re-enable interrupt
        return(ch);                      // return the char
    }
    ch = -1;
    return(ch);                          // return nothing
}


/*********************************************************
                         主 函 数                   
*********************************************************/
main()
{
    /* 通信参数Communications parameters */
    int        port     = COM1;
    int        speed    = 9600;
    int        parity   = LCR_NO_PARITY;
    int        bits     = 8;
    int        stopbits = 1;
    int        done  = FALSE;
    char       c;
    int temp;
    int SError=0;

    GSerial gs;  /* 定义GSerial类对象 */

    /* 以下代码调用GSerial类成员函数初始化串口、打开串口 */
    if (!gs.InitSerialPort(port, speed, parity, bits, stopbits))
    {
        PortBase = PortBaseAddr[port-1];  /* 得到串口基地址,中断服务程序中要用到 */
        gs.SetVects(ComIntServ);  /* 装入中断服务程序向量 */
        (); /* 打开串口 */
    }
    else
       SError=2;  /* 如果打开串口出错,则设置错误代号,这会导致退出程序 */

    /* 以下代码打印出串口号、基地址、中断号信息 */
    fprintf(stdout, "\nCOM%d, PortBase=0X%x, IntVect=0X%x\n\n",gs.m_unPortNo,gs.m_unPortBase,ComIRQ[gs.m_unPortNo-1]);

    /* 打印出终端状态,程序按ESC退出 */
    fprintf(stdout, "TURBO C TERMINAL\n"
            "...You're now in terminal mode, "
            "press [ESC] to quit...\n\n");

    /* 以下用一个循环读取串口数据,也可以从键盘敲入字符,从打开的串口发送出去
       The main loop a MSR_CTS as a dumb terminal. We repeatedly
       check the keyboard buffer, and communications buffer. */
    
    do {
        if (kbhit())
        {
            c = getch();
            /* 是否有Esc键,如有,则退出循环 */
            switch (c)
            {
                case ESC:
                    done = TRUE;  /* 这里可对其他键进行响应处理 */
                    break;
            }
            if (!done)
            {
               gs.SendChar( c );  /* 如果不是Esc键,则从串口将键入的字符发送 */
               fprintf(stdout,"%c",c);  /* 同时,在屏幕上显示该字符 */
            }
        }
        c = ReadChar();  /* 读接受数据缓冲区 */
        if (c != -1)     /* '-1' is the END signal of a string */
        {
            fprintf(stdout,"%c",c);  /* 在屏幕上显示接收到的字符 */
        }
       //    fprintf(stdout,"%d",testtemp);

    } while ((!done) && (!SError));

    gs.CloseSerialPort();  /* 关闭串口,恢复现场 */

    /* 下面是错误显示或正常退出Check for errors */
    switch (SError)
    {
        case NO_ERROR: fprintf(stderr, "\nbye.\n");
                      return (0);

        case BUF_OVFL: fprintf(stderr, "\nBuffer Overflow.\n");
                      return (99);
        case 2:   fprintf(stderr,"\n Cannot init serial port");
                       return(2);
        default:      fprintf(stderr, "\nUnknown Error, SError = %d\n",
                              SError);
                      return (99);
    }
}



[ 本帖最后由 li343 于 2009-10-9 13:35 编辑 ]
搜索更多相关主题的帖子: 编译 运行 请求 
2009-10-09 10:12
刘暮哲
Rank: 2
来 自:江苏
等 级:论坛游民
帖 子:75
专家分:83
注 册:2009-9-25
收藏
得分:3 

做最好的自己
2009-10-09 20:50
pgy
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:C
等 级:小飞侠
威 望:8
帖 子:1248
专家分:2329
注 册:2009-9-23
收藏
得分:3 
哇哇

我可好玩啦...不信你玩玩^_^
2009-10-09 21:35
viky2003
Rank: 5Rank: 5
等 级:职业侠客
帖 子:375
专家分:383
注 册:2007-4-11
收藏
得分:3 
dos.h不是标准的头文件,应该是TC所有的头文件,所以你要编译,请找TC3.0。


要练习算法就来http:///!!有挑战哦!!
2009-10-09 21:57
jiayou_yatou
Rank: 2
等 级:论坛游民
帖 子:33
专家分:15
注 册:2010-5-17
收藏
得分:0 
你好,我也想请教这个问题。
2010-05-17 20:41
快速回复:请求帮助:修改C程序使之在VC++6.0下编译运行
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035207 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved